@ansvar/india-law-mcp 1.1.1

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.
Files changed (116) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +404 -0
  3. package/data/database.db +0 -0
  4. package/dist/capabilities.d.ts +16 -0
  5. package/dist/capabilities.d.ts.map +1 -0
  6. package/dist/capabilities.js +45 -0
  7. package/dist/capabilities.js.map +1 -0
  8. package/dist/citation/formatter.d.ts +11 -0
  9. package/dist/citation/formatter.d.ts.map +1 -0
  10. package/dist/citation/formatter.js +35 -0
  11. package/dist/citation/formatter.js.map +1 -0
  12. package/dist/citation/parser.d.ts +12 -0
  13. package/dist/citation/parser.d.ts.map +1 -0
  14. package/dist/citation/parser.js +69 -0
  15. package/dist/citation/parser.js.map +1 -0
  16. package/dist/citation/validator.d.ts +10 -0
  17. package/dist/citation/validator.d.ts.map +1 -0
  18. package/dist/citation/validator.js +74 -0
  19. package/dist/citation/validator.js.map +1 -0
  20. package/dist/index.d.ts +8 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +83 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/tools/about.d.ts +35 -0
  25. package/dist/tools/about.d.ts.map +1 -0
  26. package/dist/tools/about.js +51 -0
  27. package/dist/tools/about.js.map +1 -0
  28. package/dist/tools/build-legal-stance.d.ts +29 -0
  29. package/dist/tools/build-legal-stance.d.ts.map +1 -0
  30. package/dist/tools/build-legal-stance.js +54 -0
  31. package/dist/tools/build-legal-stance.js.map +1 -0
  32. package/dist/tools/check-currency.d.ts +23 -0
  33. package/dist/tools/check-currency.d.ts.map +1 -0
  34. package/dist/tools/check-currency.js +49 -0
  35. package/dist/tools/check-currency.js.map +1 -0
  36. package/dist/tools/format-citation.d.ts +18 -0
  37. package/dist/tools/format-citation.d.ts.map +1 -0
  38. package/dist/tools/format-citation.js +38 -0
  39. package/dist/tools/format-citation.js.map +1 -0
  40. package/dist/tools/get-eu-basis.d.ts +26 -0
  41. package/dist/tools/get-eu-basis.d.ts.map +1 -0
  42. package/dist/tools/get-eu-basis.js +69 -0
  43. package/dist/tools/get-eu-basis.js.map +1 -0
  44. package/dist/tools/get-indian-implementations.d.ts +25 -0
  45. package/dist/tools/get-indian-implementations.d.ts.map +1 -0
  46. package/dist/tools/get-indian-implementations.js +48 -0
  47. package/dist/tools/get-indian-implementations.js.map +1 -0
  48. package/dist/tools/get-provision-eu-basis.d.ts +18 -0
  49. package/dist/tools/get-provision-eu-basis.d.ts.map +1 -0
  50. package/dist/tools/get-provision-eu-basis.js +55 -0
  51. package/dist/tools/get-provision-eu-basis.js.map +1 -0
  52. package/dist/tools/get-provision.d.ts +28 -0
  53. package/dist/tools/get-provision.d.ts.map +1 -0
  54. package/dist/tools/get-provision.js +74 -0
  55. package/dist/tools/get-provision.js.map +1 -0
  56. package/dist/tools/list-sources.d.ts +29 -0
  57. package/dist/tools/list-sources.d.ts.map +1 -0
  58. package/dist/tools/list-sources.js +78 -0
  59. package/dist/tools/list-sources.js.map +1 -0
  60. package/dist/tools/registry.d.ts +13 -0
  61. package/dist/tools/registry.d.ts.map +1 -0
  62. package/dist/tools/registry.js +398 -0
  63. package/dist/tools/registry.js.map +1 -0
  64. package/dist/tools/search-eu-implementations.d.ts +32 -0
  65. package/dist/tools/search-eu-implementations.d.ts.map +1 -0
  66. package/dist/tools/search-eu-implementations.js +63 -0
  67. package/dist/tools/search-eu-implementations.js.map +1 -0
  68. package/dist/tools/search-legislation.d.ts +24 -0
  69. package/dist/tools/search-legislation.d.ts.map +1 -0
  70. package/dist/tools/search-legislation.js +60 -0
  71. package/dist/tools/search-legislation.js.map +1 -0
  72. package/dist/tools/validate-citation.d.ts +20 -0
  73. package/dist/tools/validate-citation.d.ts.map +1 -0
  74. package/dist/tools/validate-citation.js +37 -0
  75. package/dist/tools/validate-citation.js.map +1 -0
  76. package/dist/tools/validate-eu-compliance.d.ts +20 -0
  77. package/dist/tools/validate-eu-compliance.d.ts.map +1 -0
  78. package/dist/tools/validate-eu-compliance.js +63 -0
  79. package/dist/tools/validate-eu-compliance.js.map +1 -0
  80. package/dist/types/citations.d.ts +21 -0
  81. package/dist/types/citations.d.ts.map +1 -0
  82. package/dist/types/citations.js +2 -0
  83. package/dist/types/citations.js.map +1 -0
  84. package/dist/types/documents.d.ts +16 -0
  85. package/dist/types/documents.d.ts.map +1 -0
  86. package/dist/types/documents.js +2 -0
  87. package/dist/types/documents.js.map +1 -0
  88. package/dist/types/eu-references.d.ts +54 -0
  89. package/dist/types/eu-references.d.ts.map +1 -0
  90. package/dist/types/eu-references.js +2 -0
  91. package/dist/types/eu-references.js.map +1 -0
  92. package/dist/types/index.d.ts +5 -0
  93. package/dist/types/index.d.ts.map +1 -0
  94. package/dist/types/index.js +2 -0
  95. package/dist/types/index.js.map +1 -0
  96. package/dist/types/provisions.d.ts +18 -0
  97. package/dist/types/provisions.d.ts.map +1 -0
  98. package/dist/types/provisions.js +2 -0
  99. package/dist/types/provisions.js.map +1 -0
  100. package/dist/utils/as-of-date.d.ts +2 -0
  101. package/dist/utils/as-of-date.d.ts.map +1 -0
  102. package/dist/utils/as-of-date.js +23 -0
  103. package/dist/utils/as-of-date.js.map +1 -0
  104. package/dist/utils/fts-query.d.ts +13 -0
  105. package/dist/utils/fts-query.d.ts.map +1 -0
  106. package/dist/utils/fts-query.js +56 -0
  107. package/dist/utils/fts-query.js.map +1 -0
  108. package/dist/utils/metadata.d.ts +15 -0
  109. package/dist/utils/metadata.d.ts.map +1 -0
  110. package/dist/utils/metadata.js +29 -0
  111. package/dist/utils/metadata.js.map +1 -0
  112. package/dist/utils/statute-id.d.ts +13 -0
  113. package/dist/utils/statute-id.d.ts.map +1 -0
  114. package/dist/utils/statute-id.js +69 -0
  115. package/dist/utils/statute-id.js.map +1 -0
  116. package/package.json +82 -0
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Indian legal citation formatter.
3
+ *
4
+ * Formats:
5
+ * full: "Section 4, Digital Personal Data Protection Act, 2023"
6
+ * short: "s. 4 DPDPA 2023"
7
+ * pinpoint: "s. 4(1)(a)"
8
+ */
9
+ export function formatCitation(parsed, format = 'full') {
10
+ if (!parsed.valid || !parsed.section) {
11
+ return '';
12
+ }
13
+ const pinpoint = buildPinpoint(parsed);
14
+ switch (format) {
15
+ case 'full':
16
+ return `Section ${pinpoint}, ${parsed.title ?? ''}, ${parsed.year ?? ''}`.trim().replace(/,\s*$/, '');
17
+ case 'short':
18
+ return `s. ${pinpoint} ${parsed.title ?? ''} ${parsed.year ?? ''}`.trim();
19
+ case 'pinpoint':
20
+ return `s. ${pinpoint}`;
21
+ default:
22
+ return `Section ${pinpoint}, ${parsed.title ?? ''}, ${parsed.year ?? ''}`.trim().replace(/,\s*$/, '');
23
+ }
24
+ }
25
+ function buildPinpoint(parsed) {
26
+ let ref = parsed.section ?? '';
27
+ if (parsed.subsection) {
28
+ ref += `(${parsed.subsection})`;
29
+ }
30
+ if (parsed.clause) {
31
+ ref += `(${parsed.clause})`;
32
+ }
33
+ return ref;
34
+ }
35
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/citation/formatter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,UAAU,cAAc,CAC5B,MAAsB,EACtB,SAAyB,MAAM;IAE/B,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAEvC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM;YACT,OAAO,WAAW,QAAQ,KAAK,MAAM,CAAC,KAAK,IAAI,EAAE,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAExG,KAAK,OAAO;YACV,OAAO,MAAM,QAAQ,IAAI,MAAM,CAAC,KAAK,IAAI,EAAE,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;QAE5E,KAAK,UAAU;YACb,OAAO,MAAM,QAAQ,EAAE,CAAC;QAE1B;YACE,OAAO,WAAW,QAAQ,KAAK,MAAM,CAAC,KAAK,IAAI,EAAE,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1G,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,MAAsB;IAC3C,IAAI,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IAC/B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,GAAG,IAAI,IAAI,MAAM,CAAC,UAAU,GAAG,CAAC;IAClC,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,GAAG,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;IAC9B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Indian legal citation parser.
3
+ *
4
+ * Parses citations like:
5
+ * "Section 4, Digital Personal Data Protection Act, 2023"
6
+ * "s. 43A, Information Technology Act, 2000"
7
+ * "S. 66 IT Act 2000"
8
+ * "Art. 21, Constitution of India"
9
+ */
10
+ import type { ParsedCitation } from '../types/index.js';
11
+ export declare function parseCitation(citation: string): ParsedCitation;
12
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/citation/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAiBxD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAgC9D"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Indian legal citation parser.
3
+ *
4
+ * Parses citations like:
5
+ * "Section 4, Digital Personal Data Protection Act, 2023"
6
+ * "s. 43A, Information Technology Act, 2000"
7
+ * "S. 66 IT Act 2000"
8
+ * "Art. 21, Constitution of India"
9
+ */
10
+ // Full citation: "Section 4, Digital Personal Data Protection Act, 2023"
11
+ const FULL_CITATION = /^(?:Section|s\.?|Art\.?)\s+(\d+[A-Za-z]?(?:\(\d+\))*(?:\([a-z]\))*)\s*,?\s+(.+?)\s*,?\s*(\d{4})$/i;
12
+ // Short citation: "s. 43A IT Act 2000"
13
+ const SHORT_CITATION = /^(?:s\.?|S\.?)\s+(\d+[A-Za-z]?(?:\(\d+\))*(?:\([a-z]\))*)\s+(.+?)\s+(\d{4})$/i;
14
+ // Trailing section citation: "Digital Personal Data Protection Act, 2023, s. 4"
15
+ const TRAILING_SECTION = /^(.+?)\s*,?\s*(\d{4})\s*,?\s*(?:Section|s\.?|Art\.?)\s*(\d+[A-Za-z]?(?:\(\d+\))*(?:\([a-z]\))*)$/i;
16
+ // Article citation for Constitution: "Article 21, Constitution of India"
17
+ const ARTICLE_CITATION = /^(?:Article|Art\.?)\s+(\d+[A-Za-z]?)\s*,?\s+(.+?)(?:\s*,?\s*(\d{4}))?$/i;
18
+ // Section with subsection: "43A(1)(a)"
19
+ const SECTION_REF = /^(\d+[A-Za-z]?)(?:\((\d+)\))?(?:\(([a-z])\))?$/;
20
+ export function parseCitation(citation) {
21
+ const trimmed = citation.trim();
22
+ // Try article citation (Constitution)
23
+ let match = trimmed.match(ARTICLE_CITATION);
24
+ if (match && /constitution/i.test(match[2])) {
25
+ return parseSection(match[1], match[2], match[3] ? parseInt(match[3], 10) : 1950, 'statute');
26
+ }
27
+ // Try full citation
28
+ match = trimmed.match(FULL_CITATION);
29
+ if (match) {
30
+ return parseSection(match[1], match[2], parseInt(match[3], 10), 'statute');
31
+ }
32
+ // Try short citation
33
+ match = trimmed.match(SHORT_CITATION);
34
+ if (match) {
35
+ return parseSection(match[1], match[2], parseInt(match[3], 10), 'statute');
36
+ }
37
+ // Try trailing section citation
38
+ match = trimmed.match(TRAILING_SECTION);
39
+ if (match) {
40
+ return parseSection(match[3], match[1], parseInt(match[2], 10), 'statute');
41
+ }
42
+ return {
43
+ valid: false,
44
+ type: 'unknown',
45
+ error: `Could not parse Indian citation: "${trimmed}"`,
46
+ };
47
+ }
48
+ function parseSection(sectionStr, title, year, type) {
49
+ const sectionMatch = sectionStr.match(SECTION_REF);
50
+ if (!sectionMatch) {
51
+ return {
52
+ valid: true,
53
+ type,
54
+ title: title.trim(),
55
+ year,
56
+ section: sectionStr,
57
+ };
58
+ }
59
+ return {
60
+ valid: true,
61
+ type,
62
+ title: title.trim(),
63
+ year,
64
+ section: sectionMatch[1],
65
+ subsection: sectionMatch[2] || undefined,
66
+ clause: sectionMatch[3] || undefined,
67
+ };
68
+ }
69
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/citation/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,yEAAyE;AACzE,MAAM,aAAa,GAAG,mGAAmG,CAAC;AAE1H,uCAAuC;AACvC,MAAM,cAAc,GAAG,+EAA+E,CAAC;AAEvG,gFAAgF;AAChF,MAAM,gBAAgB,GAAG,mGAAmG,CAAC;AAE7H,yEAAyE;AACzE,MAAM,gBAAgB,GAAG,yEAAyE,CAAC;AAEnG,uCAAuC;AACvC,MAAM,WAAW,GAAG,gDAAgD,CAAC;AAErE,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEhC,sCAAsC;IACtC,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC5C,IAAI,KAAK,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/F,CAAC;IAED,oBAAoB;IACpB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACrC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;IAC7E,CAAC;IAED,qBAAqB;IACrB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACtC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;IAC7E,CAAC;IAED,gCAAgC;IAChC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACxC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO;QACL,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,qCAAqC,OAAO,GAAG;KACvD,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CACnB,UAAkB,EAClB,KAAa,EACb,IAAY,EACZ,IAAwC;IAExC,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACnD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO;YACL,KAAK,EAAE,IAAI;YACX,IAAI;YACJ,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;YACnB,IAAI;YACJ,OAAO,EAAE,UAAU;SACpB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE,IAAI;QACX,IAAI;QACJ,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE;QACnB,IAAI;QACJ,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;QACxB,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,SAAS;QACxC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,SAAS;KACrC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Indian legal citation validator.
3
+ *
4
+ * Validates a citation string against the database to ensure the document
5
+ * and provision actually exist (zero-hallucination enforcement).
6
+ */
7
+ import type { Database } from '@ansvar/mcp-sqlite';
8
+ import type { ValidationResult } from '../types/index.js';
9
+ export declare function validateCitation(db: Database, citation: string): ValidationResult;
10
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/citation/validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAsFjF"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Indian legal citation validator.
3
+ *
4
+ * Validates a citation string against the database to ensure the document
5
+ * and provision actually exist (zero-hallucination enforcement).
6
+ */
7
+ import { parseCitation } from './parser.js';
8
+ export function validateCitation(db, citation) {
9
+ const parsed = parseCitation(citation);
10
+ const warnings = [];
11
+ if (!parsed.valid) {
12
+ return {
13
+ citation: parsed,
14
+ document_exists: false,
15
+ provision_exists: false,
16
+ warnings: [parsed.error ?? 'Invalid citation format'],
17
+ };
18
+ }
19
+ // Look up document by title match
20
+ const titlePattern = parsed.year
21
+ ? `%${parsed.title}%${parsed.year}%`
22
+ : `%${parsed.title}%`;
23
+ const doc = db.prepare("SELECT id, title, status FROM legal_documents WHERE title LIKE ? LIMIT 1").get(titlePattern);
24
+ if (!doc) {
25
+ return {
26
+ citation: parsed,
27
+ document_exists: false,
28
+ provision_exists: false,
29
+ warnings: [`Document "${parsed.title}${parsed.year ? ', ' + parsed.year : ''}" not found in database`],
30
+ };
31
+ }
32
+ if (doc.status === 'repealed') {
33
+ warnings.push('This statute has been repealed');
34
+ }
35
+ // Check provision existence
36
+ let provisionExists = false;
37
+ if (parsed.section) {
38
+ const pinpoint = [
39
+ parsed.section,
40
+ parsed.subsection ? `(${parsed.subsection})` : '',
41
+ parsed.clause ? `(${parsed.clause})` : '',
42
+ ].join('');
43
+ const provisionRef = `s${pinpoint}`;
44
+ const allowPrefixMatch = parsed.subsection == null && parsed.clause == null;
45
+ const prov = db.prepare(`SELECT 1
46
+ FROM legal_provisions
47
+ WHERE document_id = ?
48
+ AND (
49
+ provision_ref = ?
50
+ OR section = ?
51
+ OR REPLACE(REPLACE(section, '((', '('), '))', ')') = ?
52
+ OR (
53
+ ? = 1
54
+ AND (
55
+ provision_ref LIKE ?
56
+ OR REPLACE(REPLACE(section, '((', '('), '))', ')') LIKE ?
57
+ )
58
+ )
59
+ )`).get(doc.id, provisionRef, pinpoint, pinpoint, allowPrefixMatch ? 1 : 0, `${provisionRef}(%`, `${pinpoint}(%`);
60
+ provisionExists = !!prov;
61
+ if (!provisionExists) {
62
+ warnings.push(`Section ${pinpoint} not found in ${doc.title}`);
63
+ }
64
+ }
65
+ return {
66
+ citation: parsed,
67
+ document_exists: true,
68
+ provision_exists: provisionExists,
69
+ document_title: doc.title,
70
+ status: doc.status,
71
+ warnings,
72
+ };
73
+ }
74
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/citation/validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,UAAU,gBAAgB,CAAC,EAAY,EAAE,QAAgB;IAC7D,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO;YACL,QAAQ,EAAE,MAAM;YAChB,eAAe,EAAE,KAAK;YACtB,gBAAgB,EAAE,KAAK;YACvB,QAAQ,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,yBAAyB,CAAC;SACtD,CAAC;IACJ,CAAC;IAED,kCAAkC;IAClC,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI;QAC9B,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,GAAG;QACpC,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC;IAExB,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CACpB,0EAA0E,CAC3E,CAAC,GAAG,CAAC,YAAY,CAA8D,CAAC;IAEjF,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO;YACL,QAAQ,EAAE,MAAM;YAChB,eAAe,EAAE,KAAK;YACtB,gBAAgB,EAAE,KAAK;YACvB,QAAQ,EAAE,CAAC,aAAa,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,yBAAyB,CAAC;SACvG,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAClD,CAAC;IAED,4BAA4B;IAC5B,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG;YACf,MAAM,CAAC,OAAO;YACd,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE;YACjD,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE;SAC1C,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACX,MAAM,YAAY,GAAG,IAAI,QAAQ,EAAE,CAAC;QACpC,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC;QAE5E,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CACrB;;;;;;;;;;;;;;WAcK,CACN,CAAC,GAAG,CACH,GAAG,CAAC,EAAE,EACN,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACxB,GAAG,YAAY,IAAI,EACnB,GAAG,QAAQ,IAAI,CAChB,CAAC;QACF,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC;QAEzB,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,QAAQ,CAAC,IAAI,CAAC,WAAW,QAAQ,iBAAiB,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,MAAM;QAChB,eAAe,EAAE,IAAI;QACrB,gBAAgB,EAAE,eAAe;QACjC,cAAc,EAAE,GAAG,CAAC,KAAK;QACzB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ;KACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * India Law MCP Server — stdio entry point.
4
+ *
5
+ * Provides Indian legislation search via Model Context Protocol.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;GAIG"}
package/dist/index.js ADDED
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * India Law MCP Server — stdio entry point.
4
+ *
5
+ * Provides Indian legislation search via Model Context Protocol.
6
+ */
7
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
9
+ import Database from '@ansvar/mcp-sqlite';
10
+ import { join, dirname } from 'path';
11
+ import { fileURLToPath } from 'url';
12
+ import { createHash } from 'crypto';
13
+ import { readFileSync } from 'fs';
14
+ import { registerTools } from './tools/registry.js';
15
+ import { detectCapabilities, readDbMetadata } from './capabilities.js';
16
+ const __dirname = dirname(fileURLToPath(import.meta.url));
17
+ const SERVER_NAME = 'india-law-mcp';
18
+ const SERVER_VERSION = '1.0.0';
19
+ const DB_ENV_VAR = 'INDIA_LAW_DB_PATH';
20
+ function resolveDbPath() {
21
+ if (process.env[DB_ENV_VAR]) {
22
+ return process.env[DB_ENV_VAR];
23
+ }
24
+ // Check for database relative to the package
25
+ return join(__dirname, '..', 'data', 'database.db');
26
+ }
27
+ let db = null;
28
+ function getDb() {
29
+ if (!db) {
30
+ const dbPath = resolveDbPath();
31
+ db = new Database(dbPath, { readonly: true });
32
+ db.pragma('foreign_keys = ON');
33
+ const caps = detectCapabilities(db);
34
+ const meta = readDbMetadata(db);
35
+ console.error(`[${SERVER_NAME}] DB opened: tier=${meta.tier}, caps=[${[...caps].join(',')}]`);
36
+ }
37
+ return db;
38
+ }
39
+ function computeAboutContext() {
40
+ const dbPath = resolveDbPath();
41
+ let fingerprint = 'unknown';
42
+ let dbBuilt = 'unknown';
43
+ try {
44
+ const buf = readFileSync(dbPath);
45
+ fingerprint = createHash('sha256').update(buf).digest('hex').slice(0, 12);
46
+ }
47
+ catch {
48
+ // DB might not exist in dev
49
+ }
50
+ try {
51
+ const database = getDb();
52
+ const row = database.prepare("SELECT value FROM db_metadata WHERE key = 'built_at'").get();
53
+ if (row)
54
+ dbBuilt = row.value;
55
+ }
56
+ catch {
57
+ // Ignore
58
+ }
59
+ return { version: SERVER_VERSION, fingerprint, dbBuilt };
60
+ }
61
+ async function main() {
62
+ const database = getDb();
63
+ const aboutContext = computeAboutContext();
64
+ const server = new Server({ name: SERVER_NAME, version: SERVER_VERSION }, { capabilities: { tools: {} } });
65
+ registerTools(server, database, aboutContext);
66
+ const transport = new StdioServerTransport();
67
+ await server.connect(transport);
68
+ console.error(`[${SERVER_NAME}] Server running on stdio`);
69
+ const cleanup = () => {
70
+ if (db) {
71
+ db.close();
72
+ db = null;
73
+ }
74
+ process.exit(0);
75
+ };
76
+ process.on('SIGINT', cleanup);
77
+ process.on('SIGTERM', cleanup);
78
+ }
79
+ main().catch((err) => {
80
+ console.error(`[${SERVER_NAME}] Fatal error:`, err);
81
+ process.exit(1);
82
+ });
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type Database from '@ansvar/mcp-sqlite';
2
+ export interface AboutContext {
3
+ version: string;
4
+ fingerprint: string;
5
+ dbBuilt: string;
6
+ }
7
+ export interface AboutResult {
8
+ server: {
9
+ name: string;
10
+ package: string;
11
+ version: string;
12
+ suite: string;
13
+ repository: string;
14
+ };
15
+ dataset: {
16
+ fingerprint: string;
17
+ built: string;
18
+ jurisdiction: string;
19
+ content_basis: string;
20
+ counts: Record<string, number>;
21
+ };
22
+ provenance: {
23
+ sources: string[];
24
+ license: string;
25
+ authenticity_note: string;
26
+ };
27
+ security: {
28
+ access_model: string;
29
+ network_access: boolean;
30
+ filesystem_access: boolean;
31
+ arbitrary_code: boolean;
32
+ };
33
+ }
34
+ export declare function getAbout(db: InstanceType<typeof Database>, context: AboutContext): AboutResult;
35
+ //# sourceMappingURL=about.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"about.d.ts","sourceRoot":"","sources":["../../src/tools/about.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,oBAAoB,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAChC,CAAC;IACF,UAAU,EAAE;QACV,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,QAAQ,EAAE;QACR,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,OAAO,CAAC;QACxB,iBAAiB,EAAE,OAAO,CAAC;QAC3B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;CACH;AAWD,wBAAgB,QAAQ,CACtB,EAAE,EAAE,YAAY,CAAC,OAAO,QAAQ,CAAC,EACjC,OAAO,EAAE,YAAY,GACpB,WAAW,CA2Cb"}
@@ -0,0 +1,51 @@
1
+ function safeCount(db, sql) {
2
+ try {
3
+ const row = db.prepare(sql).get();
4
+ return row ? Number(row.count) : 0;
5
+ }
6
+ catch {
7
+ return 0;
8
+ }
9
+ }
10
+ export function getAbout(db, context) {
11
+ return {
12
+ server: {
13
+ name: 'India Law MCP',
14
+ package: '@ansvar/india-law-mcp',
15
+ version: context.version,
16
+ suite: 'Ansvar Compliance Suite',
17
+ repository: 'https://github.com/Ansvar-Systems/india-law-mcp',
18
+ },
19
+ dataset: {
20
+ fingerprint: context.fingerprint,
21
+ built: context.dbBuilt,
22
+ jurisdiction: 'India (IN)',
23
+ content_basis: 'Indian legislation from India Code (indiacode.nic.in). ' +
24
+ 'Covers DPDPA 2023, IT Act 2000, Companies Act 2013, Consumer Protection Act 2019, ' +
25
+ 'Aadhaar Act 2016, and related subordinate legislation.',
26
+ counts: {
27
+ legal_documents: safeCount(db, 'SELECT COUNT(*) as count FROM legal_documents'),
28
+ legal_provisions: safeCount(db, 'SELECT COUNT(*) as count FROM legal_provisions'),
29
+ eu_documents: safeCount(db, 'SELECT COUNT(*) as count FROM eu_documents'),
30
+ eu_references: safeCount(db, 'SELECT COUNT(*) as count FROM eu_references'),
31
+ },
32
+ },
33
+ provenance: {
34
+ sources: [
35
+ 'India Code / indiacode.nic.in (Central Acts)',
36
+ 'legislative.gov.in (subordinate legislation)',
37
+ 'meity.gov.in (IT rules, CERT-In directions)',
38
+ ],
39
+ license: 'Apache-2.0 (server code). Legal source texts under Government Open Data License India.',
40
+ authenticity_note: 'Statute text is derived from India Code (indiacode.nic.in) open data. ' +
41
+ 'Verify against official publications when legal certainty is required.',
42
+ },
43
+ security: {
44
+ access_model: 'read-only',
45
+ network_access: false,
46
+ filesystem_access: false,
47
+ arbitrary_code: false,
48
+ },
49
+ };
50
+ }
51
+ //# sourceMappingURL=about.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"about.js","sourceRoot":"","sources":["../../src/tools/about.ts"],"names":[],"mappings":"AAoCA,SAAS,SAAS,CAAC,EAAiC,EAAE,GAAW;IAC/D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAmC,CAAC;QACnE,OAAO,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,EAAiC,EACjC,OAAqB;IAErB,OAAO;QACL,MAAM,EAAE;YACN,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,uBAAuB;YAChC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,KAAK,EAAE,yBAAyB;YAChC,UAAU,EAAE,iDAAiD;SAC9D;QACD,OAAO,EAAE;YACP,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,KAAK,EAAE,OAAO,CAAC,OAAO;YACtB,YAAY,EAAE,YAAY;YAC1B,aAAa,EACX,yDAAyD;gBACzD,oFAAoF;gBACpF,wDAAwD;YAC1D,MAAM,EAAE;gBACN,eAAe,EAAE,SAAS,CAAC,EAAE,EAAE,+CAA+C,CAAC;gBAC/E,gBAAgB,EAAE,SAAS,CAAC,EAAE,EAAE,gDAAgD,CAAC;gBACjF,YAAY,EAAE,SAAS,CAAC,EAAE,EAAE,4CAA4C,CAAC;gBACzE,aAAa,EAAE,SAAS,CAAC,EAAE,EAAE,6CAA6C,CAAC;aAC5E;SACF;QACD,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,8CAA8C;gBAC9C,8CAA8C;gBAC9C,6CAA6C;aAC9C;YACD,OAAO,EACL,wFAAwF;YAC1F,iBAAiB,EACf,wEAAwE;gBACxE,wEAAwE;SAC3E;QACD,QAAQ,EAAE;YACR,YAAY,EAAE,WAAW;YACzB,cAAc,EAAE,KAAK;YACrB,iBAAiB,EAAE,KAAK;YACxB,cAAc,EAAE,KAAK;SACtB;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * build_legal_stance — Aggregate citations for a legal question.
3
+ */
4
+ import type { Database } from '@ansvar/mcp-sqlite';
5
+ import { type ToolResponse } from '../utils/metadata.js';
6
+ export interface BuildLegalStanceInput {
7
+ query: string;
8
+ document_id?: string;
9
+ include_case_law?: boolean;
10
+ include_preparatory_works?: boolean;
11
+ as_of_date?: string;
12
+ limit?: number;
13
+ }
14
+ interface ProvisionHit {
15
+ document_id: string;
16
+ document_title: string;
17
+ provision_ref: string;
18
+ title: string | null;
19
+ snippet: string;
20
+ relevance: number;
21
+ }
22
+ export interface LegalStanceResult {
23
+ query: string;
24
+ provisions: ProvisionHit[];
25
+ total_citations: number;
26
+ }
27
+ export declare function buildLegalStance(db: Database, input: BuildLegalStanceInput): Promise<ToolResponse<LegalStanceResult>>;
28
+ export {};
29
+ //# sourceMappingURL=build-legal-stance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-legal-stance.d.ts","sourceRoot":"","sources":["../../src/tools/build-legal-stance.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEnF,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,YAAY;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAKD,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,CAqD1C"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * build_legal_stance — Aggregate citations for a legal question.
3
+ */
4
+ import { buildFtsQueryVariants } from '../utils/fts-query.js';
5
+ import { generateResponseMetadata } from '../utils/metadata.js';
6
+ const DEFAULT_LIMIT = 5;
7
+ const MAX_LIMIT = 20;
8
+ export async function buildLegalStance(db, input) {
9
+ if (!input.query || input.query.trim().length === 0) {
10
+ return {
11
+ results: { query: '', provisions: [], total_citations: 0 },
12
+ _metadata: generateResponseMetadata(db)
13
+ };
14
+ }
15
+ const limit = Math.min(Math.max(input.limit ?? DEFAULT_LIMIT, 1), MAX_LIMIT);
16
+ const queryVariants = buildFtsQueryVariants(input.query);
17
+ let provSql = `
18
+ SELECT
19
+ lp.document_id,
20
+ ld.title as document_title,
21
+ lp.provision_ref,
22
+ lp.title,
23
+ snippet(provisions_fts, 0, '>>>', '<<<', '...', 32) as snippet,
24
+ bm25(provisions_fts) as relevance
25
+ FROM provisions_fts
26
+ JOIN legal_provisions lp ON lp.id = provisions_fts.rowid
27
+ JOIN legal_documents ld ON ld.id = lp.document_id
28
+ WHERE provisions_fts MATCH ?
29
+ `;
30
+ const provParams = [];
31
+ if (input.document_id) {
32
+ provSql += ` AND lp.document_id = ?`;
33
+ provParams.push(input.document_id);
34
+ }
35
+ provSql += ` ORDER BY relevance LIMIT ?`;
36
+ provParams.push(limit);
37
+ const runProvisionQuery = (ftsQuery) => {
38
+ const bound = [ftsQuery, ...provParams];
39
+ return db.prepare(provSql).all(...bound);
40
+ };
41
+ let provisions = runProvisionQuery(queryVariants.primary);
42
+ if (provisions.length === 0 && queryVariants.fallback) {
43
+ provisions = runProvisionQuery(queryVariants.fallback);
44
+ }
45
+ return {
46
+ results: {
47
+ query: input.query,
48
+ provisions,
49
+ total_citations: provisions.length,
50
+ },
51
+ _metadata: generateResponseMetadata(db)
52
+ };
53
+ }
54
+ //# sourceMappingURL=build-legal-stance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-legal-stance.js","sourceRoot":"","sources":["../../src/tools/build-legal-stance.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,wBAAwB,EAAqB,MAAM,sBAAsB,CAAC;AA0BnF,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,EAAY,EACZ,KAA4B;IAE5B,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,OAAO;YACL,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,eAAe,EAAE,CAAC,EAAE;YAC1D,SAAS,EAAE,wBAAwB,CAAC,EAAE,CAAC;SACxC,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,aAAa,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAC7E,MAAM,aAAa,GAAG,qBAAqB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAEzD,IAAI,OAAO,GAAG;;;;;;;;;;;;GAYb,CAAC;IAEF,MAAM,UAAU,GAAwB,EAAE,CAAC;IAE3C,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,OAAO,IAAI,yBAAyB,CAAC;QACrC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,IAAI,6BAA6B,CAAC;IACzC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEvB,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAkB,EAAE;QAC7D,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,GAAG,UAAU,CAAC,CAAC;QACxC,OAAO,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAmB,CAAC;IAC7D,CAAC,CAAC;IAEF,IAAI,UAAU,GAAG,iBAAiB,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC1D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,QAAQ,EAAE,CAAC;QACtD,UAAU,GAAG,iBAAiB,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,UAAU;YACV,eAAe,EAAE,UAAU,CAAC,MAAM;SACnC;QACD,SAAS,EAAE,wBAAwB,CAAC,EAAE,CAAC;KACxC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * check_currency — Check if an Indian statute is current (in force).
3
+ */
4
+ import type { Database } from '@ansvar/mcp-sqlite';
5
+ import { type ToolResponse } from '../utils/metadata.js';
6
+ export interface CheckCurrencyInput {
7
+ document_id: string;
8
+ provision_ref?: string;
9
+ as_of_date?: string;
10
+ }
11
+ export interface CurrencyResult {
12
+ document_id: string;
13
+ title: string;
14
+ status: string;
15
+ type: string;
16
+ issued_date: string | null;
17
+ in_force_date: string | null;
18
+ is_current: boolean;
19
+ provision_exists?: boolean;
20
+ warnings: string[];
21
+ }
22
+ export declare function checkCurrency(db: Database, input: CheckCurrencyInput): Promise<ToolResponse<CurrencyResult | null>>;
23
+ //# sourceMappingURL=check-currency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-currency.d.ts","sourceRoot":"","sources":["../../src/tools/check-currency.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEnF,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAWD,wBAAsB,aAAa,CACjC,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,YAAY,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC,CAoD9C"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * check_currency — Check if an Indian statute is current (in force).
3
+ */
4
+ import { generateResponseMetadata } from '../utils/metadata.js';
5
+ export async function checkCurrency(db, input) {
6
+ if (!input.document_id) {
7
+ throw new Error('document_id is required');
8
+ }
9
+ const doc = db.prepare(`
10
+ SELECT id, title, status, type, issued_date, in_force_date
11
+ FROM legal_documents
12
+ WHERE id = ? OR title LIKE ?
13
+ LIMIT 1
14
+ `).get(input.document_id, `%${input.document_id}%`);
15
+ if (!doc) {
16
+ return {
17
+ results: null,
18
+ _metadata: generateResponseMetadata(db)
19
+ };
20
+ }
21
+ const warnings = [];
22
+ const isCurrent = doc.status === 'in_force';
23
+ if (doc.status === 'repealed') {
24
+ warnings.push('This statute has been repealed');
25
+ }
26
+ let provisionExists;
27
+ if (input.provision_ref) {
28
+ const prov = db.prepare('SELECT 1 FROM legal_provisions WHERE document_id = ? AND (provision_ref = ? OR section = ?)').get(doc.id, input.provision_ref, input.provision_ref);
29
+ provisionExists = !!prov;
30
+ if (!provisionExists) {
31
+ warnings.push(`Provision "${input.provision_ref}" not found in this document`);
32
+ }
33
+ }
34
+ return {
35
+ results: {
36
+ document_id: doc.id,
37
+ title: doc.title,
38
+ status: doc.status,
39
+ type: doc.type,
40
+ issued_date: doc.issued_date,
41
+ in_force_date: doc.in_force_date,
42
+ is_current: isCurrent,
43
+ provision_exists: provisionExists,
44
+ warnings,
45
+ },
46
+ _metadata: generateResponseMetadata(db)
47
+ };
48
+ }
49
+ //# sourceMappingURL=check-currency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-currency.js","sourceRoot":"","sources":["../../src/tools/check-currency.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,wBAAwB,EAAqB,MAAM,sBAAsB,CAAC;AA6BnF,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAY,EACZ,KAAyB;IAEzB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;GAKtB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,CAAC,WAAW,GAAG,CAA4B,CAAC;IAE/E,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO;YACL,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,wBAAwB,CAAC,EAAE,CAAC;SACxC,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC;IAE5C,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,eAAoC,CAAC;IACzC,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CACrB,6FAA6F,CAC9F,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;QACxD,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC;QAEzB,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,QAAQ,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,aAAa,8BAA8B,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP,WAAW,EAAE,GAAG,CAAC,EAAE;YACnB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,aAAa,EAAE,GAAG,CAAC,aAAa;YAChC,UAAU,EAAE,SAAS;YACrB,gBAAgB,EAAE,eAAe;YACjC,QAAQ;SACT;QACD,SAAS,EAAE,wBAAwB,CAAC,EAAE,CAAC;KACxC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * format_citation — Format an Indian legal citation per standard conventions.
3
+ */
4
+ import type { CitationFormat } from '../types/index.js';
5
+ import { type ToolResponse } from '../utils/metadata.js';
6
+ export interface FormatCitationInput {
7
+ citation: string;
8
+ format?: CitationFormat;
9
+ }
10
+ export interface FormatCitationResult {
11
+ input: string;
12
+ formatted: string;
13
+ type: string;
14
+ valid: boolean;
15
+ error?: string;
16
+ }
17
+ export declare function formatCitationTool(input: FormatCitationInput): Promise<ToolResponse<FormatCitationResult>>;
18
+ //# sourceMappingURL=format-citation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-citation.d.ts","sourceRoot":"","sources":["../../src/tools/format-citation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAA4B,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEnF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC,CAkC7C"}