@ansvar/ch-farm-grants-mcp 0.1.0

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 (108) hide show
  1. package/.github/workflows/check-freshness.yml +18 -0
  2. package/.github/workflows/ci.yml +21 -0
  3. package/.github/workflows/codeql.yml +25 -0
  4. package/.github/workflows/ghcr-build.yml +45 -0
  5. package/.github/workflows/gitleaks.yml +18 -0
  6. package/.github/workflows/ingest.yml +28 -0
  7. package/.github/workflows/publish.yml +24 -0
  8. package/CHANGELOG.md +22 -0
  9. package/CODEOWNERS +1 -0
  10. package/COVERAGE.md +45 -0
  11. package/DISCLAIMER.md +39 -0
  12. package/Dockerfile +26 -0
  13. package/LICENSE +17 -0
  14. package/PRIVACY.md +36 -0
  15. package/README.md +80 -0
  16. package/SECURITY.md +31 -0
  17. package/TOOLS.md +154 -0
  18. package/data/coverage.json +19 -0
  19. package/data/database.db +0 -0
  20. package/data/sources.yml +29 -0
  21. package/dist/db.d.ts +25 -0
  22. package/dist/db.d.ts.map +1 -0
  23. package/dist/db.js +167 -0
  24. package/dist/db.js.map +1 -0
  25. package/dist/http-server.d.ts +2 -0
  26. package/dist/http-server.d.ts.map +1 -0
  27. package/dist/http-server.js +261 -0
  28. package/dist/http-server.js.map +1 -0
  29. package/dist/jurisdiction.d.ts +18 -0
  30. package/dist/jurisdiction.d.ts.map +1 -0
  31. package/dist/jurisdiction.js +16 -0
  32. package/dist/jurisdiction.js.map +1 -0
  33. package/dist/metadata.d.ts +10 -0
  34. package/dist/metadata.d.ts.map +1 -0
  35. package/dist/metadata.js +22 -0
  36. package/dist/metadata.js.map +1 -0
  37. package/dist/server.d.ts +3 -0
  38. package/dist/server.d.ts.map +1 -0
  39. package/dist/server.js +207 -0
  40. package/dist/server.js.map +1 -0
  41. package/dist/tools/about.d.ts +15 -0
  42. package/dist/tools/about.d.ts.map +1 -0
  43. package/dist/tools/about.js +28 -0
  44. package/dist/tools/about.js.map +1 -0
  45. package/dist/tools/check-eligibility.d.ts +31 -0
  46. package/dist/tools/check-eligibility.d.ts.map +1 -0
  47. package/dist/tools/check-eligibility.js +57 -0
  48. package/dist/tools/check-eligibility.js.map +1 -0
  49. package/dist/tools/check-freshness.d.ts +15 -0
  50. package/dist/tools/check-freshness.d.ts.map +1 -0
  51. package/dist/tools/check-freshness.js +26 -0
  52. package/dist/tools/check-freshness.js.map +1 -0
  53. package/dist/tools/get-application-deadlines.d.ts +27 -0
  54. package/dist/tools/get-application-deadlines.d.ts.map +1 -0
  55. package/dist/tools/get-application-deadlines.js +40 -0
  56. package/dist/tools/get-application-deadlines.js.map +1 -0
  57. package/dist/tools/get-grant-details.d.ts +42 -0
  58. package/dist/tools/get-grant-details.d.ts.map +1 -0
  59. package/dist/tools/get-grant-details.js +24 -0
  60. package/dist/tools/get-grant-details.js.map +1 -0
  61. package/dist/tools/get-payment-rates.d.ts +49 -0
  62. package/dist/tools/get-payment-rates.d.ts.map +1 -0
  63. package/dist/tools/get-payment-rates.js +37 -0
  64. package/dist/tools/get-payment-rates.js.map +1 -0
  65. package/dist/tools/list-grant-options.d.ts +56 -0
  66. package/dist/tools/list-grant-options.d.ts.map +1 -0
  67. package/dist/tools/list-grant-options.js +39 -0
  68. package/dist/tools/list-grant-options.js.map +1 -0
  69. package/dist/tools/list-sources.d.ts +18 -0
  70. package/dist/tools/list-sources.d.ts.map +1 -0
  71. package/dist/tools/list-sources.js +51 -0
  72. package/dist/tools/list-sources.js.map +1 -0
  73. package/dist/tools/search-application-guidance.d.ts +36 -0
  74. package/dist/tools/search-application-guidance.d.ts.map +1 -0
  75. package/dist/tools/search-application-guidance.js +52 -0
  76. package/dist/tools/search-application-guidance.js.map +1 -0
  77. package/dist/tools/search-grants.d.ts +25 -0
  78. package/dist/tools/search-grants.d.ts.map +1 -0
  79. package/dist/tools/search-grants.js +26 -0
  80. package/dist/tools/search-grants.js.map +1 -0
  81. package/docker-compose.yml +12 -0
  82. package/eslint.config.js +26 -0
  83. package/package.json +54 -0
  84. package/scripts/ingest.ts +742 -0
  85. package/server.json +41 -0
  86. package/src/db.ts +208 -0
  87. package/src/http-server.ts +293 -0
  88. package/src/jurisdiction.ts +30 -0
  89. package/src/metadata.ts +32 -0
  90. package/src/server.ts +230 -0
  91. package/src/tools/about.ts +29 -0
  92. package/src/tools/check-eligibility.ts +81 -0
  93. package/src/tools/check-freshness.ts +42 -0
  94. package/src/tools/get-application-deadlines.ts +55 -0
  95. package/src/tools/get-grant-details.ts +51 -0
  96. package/src/tools/get-payment-rates.ts +60 -0
  97. package/src/tools/list-grant-options.ts +63 -0
  98. package/src/tools/list-sources.ts +65 -0
  99. package/src/tools/search-application-guidance.ts +59 -0
  100. package/src/tools/search-grants.ts +35 -0
  101. package/tests/db.test.ts +69 -0
  102. package/tests/helpers/seed-db.ts +188 -0
  103. package/tests/jurisdiction.test.ts +35 -0
  104. package/tests/tools/about.test.ts +23 -0
  105. package/tests/tools/check-freshness.test.ts +53 -0
  106. package/tests/tools/list-sources.test.ts +47 -0
  107. package/tests/tools/search-grants.test.ts +57 -0
  108. package/tsconfig.json +19 -0
package/dist/server.js ADDED
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
+ import { ListToolsRequestSchema, CallToolRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
+ import { z } from 'zod';
6
+ import { createDatabase } from './db.js';
7
+ import { handleAbout } from './tools/about.js';
8
+ import { handleListSources } from './tools/list-sources.js';
9
+ import { handleCheckFreshness } from './tools/check-freshness.js';
10
+ import { handleSearchGrants } from './tools/search-grants.js';
11
+ import { handleGetGrantDetails } from './tools/get-grant-details.js';
12
+ import { handleGetPaymentRates } from './tools/get-payment-rates.js';
13
+ import { handleCheckEligibility } from './tools/check-eligibility.js';
14
+ import { handleListGrantOptions } from './tools/list-grant-options.js';
15
+ import { handleGetApplicationDeadlines } from './tools/get-application-deadlines.js';
16
+ import { handleSearchApplicationGuidance } from './tools/search-application-guidance.js';
17
+ const SERVER_NAME = 'ch-farm-grants-mcp';
18
+ const SERVER_VERSION = '0.1.0';
19
+ const TOOLS = [
20
+ {
21
+ name: 'about',
22
+ description: 'Get server metadata: name, version, coverage, data sources, and links.',
23
+ inputSchema: { type: 'object', properties: {} },
24
+ },
25
+ {
26
+ name: 'list_sources',
27
+ description: 'List all data sources with authority, URL, license, and freshness info.',
28
+ inputSchema: { type: 'object', properties: {} },
29
+ },
30
+ {
31
+ name: 'check_data_freshness',
32
+ description: 'Check when data was last ingested, staleness status, and how to trigger a refresh.',
33
+ inputSchema: { type: 'object', properties: {} },
34
+ },
35
+ {
36
+ name: 'search_grants',
37
+ description: 'Search Swiss agricultural structural improvement grants, investment credits, and funding programmes. Use for broad queries about Investitionskredite, Beitraege, Meliorationen, PRE.',
38
+ inputSchema: {
39
+ type: 'object',
40
+ properties: {
41
+ query: { type: 'string', description: 'Free-text search query (German or English)' },
42
+ grant_type: { type: 'string', description: 'Filter by type: investitionskredit, beitrag, meliorationsbeitrag, pre, ressourcenprogramm, gewaesserschutz, starthilfe' },
43
+ jurisdiction: { type: 'string', description: 'ISO 3166-1 alpha-2 code (default: CH)' },
44
+ limit: { type: 'number', description: 'Max results (default: 20, max: 50)' },
45
+ },
46
+ required: ['query'],
47
+ },
48
+ },
49
+ {
50
+ name: 'get_grant_details',
51
+ description: 'Get full details for a specific grant programme: objectives, contribution rates, conditions, eligibility rules, and sub-options.',
52
+ inputSchema: {
53
+ type: 'object',
54
+ properties: {
55
+ grant_id: { type: 'string', description: 'Grant ID or name (e.g. investitionskredit-oekonomiegebaeude, starthilfe-junglandwirte)' },
56
+ jurisdiction: { type: 'string', description: 'ISO 3166-1 alpha-2 code (default: CH)' },
57
+ },
58
+ required: ['grant_id'],
59
+ },
60
+ },
61
+ {
62
+ name: 'get_payment_rates',
63
+ description: 'Get federal and cantonal contribution rates for a grant programme, with zone-specific bonuses (Berggebiet, Huegelzone).',
64
+ inputSchema: {
65
+ type: 'object',
66
+ properties: {
67
+ grant_id: { type: 'string', description: 'Grant ID or name' },
68
+ zone: { type: 'string', description: 'Altitude zone: talzone, huegelzone, bergzone_i, bergzone_ii, bergzone_iii, bergzone_iv, soemmerungsgebiet' },
69
+ jurisdiction: { type: 'string', description: 'ISO 3166-1 alpha-2 code (default: CH)' },
70
+ },
71
+ required: ['grant_id'],
72
+ },
73
+ },
74
+ {
75
+ name: 'check_eligibility',
76
+ description: 'Check which grants a farm is eligible for based on farm type, planned investment, and altitude zone.',
77
+ inputSchema: {
78
+ type: 'object',
79
+ properties: {
80
+ farm_type: { type: 'string', description: 'Farm type: milchwirtschaft, ackerbau, mutterkuhhaltung, bergbetrieb, alpwirtschaft, gemischt, gemeinschaft, junglandwirt' },
81
+ investment_type: { type: 'string', description: 'Investment type: stallbau, hofduengerlager, wohnhaus, diversifikation, alpgebaeude, wegebau, wasserversorgung, biogasanlage, kaeserei' },
82
+ zone: { type: 'string', description: 'Altitude zone: talzone, huegelzone, bergzone_i-iv, soemmerungsgebiet' },
83
+ jurisdiction: { type: 'string', description: 'ISO 3166-1 alpha-2 code (default: CH)' },
84
+ },
85
+ required: ['farm_type'],
86
+ },
87
+ },
88
+ {
89
+ name: 'list_grant_options',
90
+ description: 'List all sub-options (Massnahmen) within a grant programme, or list all grants with their option counts.',
91
+ inputSchema: {
92
+ type: 'object',
93
+ properties: {
94
+ grant_id: { type: 'string', description: 'Grant ID to list options for. If omitted, lists all grants.' },
95
+ jurisdiction: { type: 'string', description: 'ISO 3166-1 alpha-2 code (default: CH)' },
96
+ },
97
+ },
98
+ },
99
+ {
100
+ name: 'get_application_deadlines',
101
+ description: 'Get application deadlines for grants, optionally filtered by canton (2-letter code: ZH, BE, LU, etc.).',
102
+ inputSchema: {
103
+ type: 'object',
104
+ properties: {
105
+ grant_id: { type: 'string', description: 'Grant ID to check deadlines for' },
106
+ canton: { type: 'string', description: 'Canton code (e.g. ZH, BE, LU, SG, GR, VS, TI)' },
107
+ jurisdiction: { type: 'string', description: 'ISO 3166-1 alpha-2 code (default: CH)' },
108
+ },
109
+ },
110
+ },
111
+ {
112
+ name: 'search_application_guidance',
113
+ description: 'How to apply for Swiss farm grants: required documents, cantonal contacts, general process, and AGRIDEA advisory support.',
114
+ inputSchema: {
115
+ type: 'object',
116
+ properties: {
117
+ query: { type: 'string', description: 'Free-text search query about the application process' },
118
+ jurisdiction: { type: 'string', description: 'ISO 3166-1 alpha-2 code (default: CH)' },
119
+ },
120
+ required: ['query'],
121
+ },
122
+ },
123
+ ];
124
+ const SearchGrantsArgsSchema = z.object({
125
+ query: z.string(),
126
+ grant_type: z.string().optional(),
127
+ jurisdiction: z.string().optional(),
128
+ limit: z.number().optional(),
129
+ });
130
+ const GrantDetailsArgsSchema = z.object({
131
+ grant_id: z.string(),
132
+ jurisdiction: z.string().optional(),
133
+ });
134
+ const PaymentRatesArgsSchema = z.object({
135
+ grant_id: z.string(),
136
+ zone: z.string().optional(),
137
+ jurisdiction: z.string().optional(),
138
+ });
139
+ const EligibilityArgsSchema = z.object({
140
+ farm_type: z.string(),
141
+ investment_type: z.string().optional(),
142
+ zone: z.string().optional(),
143
+ jurisdiction: z.string().optional(),
144
+ });
145
+ const ListGrantOptionsArgsSchema = z.object({
146
+ grant_id: z.string().optional(),
147
+ jurisdiction: z.string().optional(),
148
+ });
149
+ const DeadlinesArgsSchema = z.object({
150
+ grant_id: z.string().optional(),
151
+ canton: z.string().optional(),
152
+ jurisdiction: z.string().optional(),
153
+ });
154
+ const GuidanceArgsSchema = z.object({
155
+ query: z.string(),
156
+ jurisdiction: z.string().optional(),
157
+ });
158
+ function textResult(data) {
159
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
160
+ }
161
+ function errorResult(message) {
162
+ return { content: [{ type: 'text', text: JSON.stringify({ error: message }) }], isError: true };
163
+ }
164
+ const db = createDatabase();
165
+ const server = new Server({ name: SERVER_NAME, version: SERVER_VERSION }, { capabilities: { tools: {} } });
166
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
167
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
168
+ const { name, arguments: args = {} } = request.params;
169
+ try {
170
+ switch (name) {
171
+ case 'about':
172
+ return textResult(handleAbout());
173
+ case 'list_sources':
174
+ return textResult(handleListSources(db));
175
+ case 'check_data_freshness':
176
+ return textResult(handleCheckFreshness(db));
177
+ case 'search_grants':
178
+ return textResult(handleSearchGrants(db, SearchGrantsArgsSchema.parse(args)));
179
+ case 'get_grant_details':
180
+ return textResult(handleGetGrantDetails(db, GrantDetailsArgsSchema.parse(args)));
181
+ case 'get_payment_rates':
182
+ return textResult(handleGetPaymentRates(db, PaymentRatesArgsSchema.parse(args)));
183
+ case 'check_eligibility':
184
+ return textResult(handleCheckEligibility(db, EligibilityArgsSchema.parse(args)));
185
+ case 'list_grant_options':
186
+ return textResult(handleListGrantOptions(db, ListGrantOptionsArgsSchema.parse(args)));
187
+ case 'get_application_deadlines':
188
+ return textResult(handleGetApplicationDeadlines(db, DeadlinesArgsSchema.parse(args)));
189
+ case 'search_application_guidance':
190
+ return textResult(handleSearchApplicationGuidance(db, GuidanceArgsSchema.parse(args)));
191
+ default:
192
+ return errorResult(`Unknown tool: ${name}`);
193
+ }
194
+ }
195
+ catch (err) {
196
+ return errorResult(err instanceof Error ? err.message : String(err));
197
+ }
198
+ });
199
+ async function main() {
200
+ const transport = new StdioServerTransport();
201
+ await server.connect(transport);
202
+ }
203
+ main().catch((err) => {
204
+ process.stderr.write(`Fatal error: ${err.message}\n`);
205
+ process.exit(1);
206
+ });
207
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export declare function handleAbout(): {
2
+ name: string;
3
+ description: string;
4
+ version: string;
5
+ jurisdiction: "CH"[];
6
+ data_sources: string[];
7
+ tools_count: number;
8
+ links: {
9
+ homepage: string;
10
+ repository: string;
11
+ mcp_network: string;
12
+ };
13
+ _meta: import("../metadata.js").Meta;
14
+ };
15
+ //# sourceMappingURL=about.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"about.d.ts","sourceRoot":"","sources":["../../src/tools/about.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW;;;;;;;;;;;;;EAyB1B"}
@@ -0,0 +1,28 @@
1
+ import { buildMeta } from '../metadata.js';
2
+ import { SUPPORTED_JURISDICTIONS } from '../jurisdiction.js';
3
+ export function handleAbout() {
4
+ return {
5
+ name: 'Switzerland Farm Grants MCP',
6
+ description: 'Swiss agricultural structural improvement grants based on the Strukturverbesserungsverordnung (SVV), ' +
7
+ 'BLW investment credit guidelines, and cantonal funding programmes. Covers Investitionskredite (interest-free ' +
8
+ 'loans), Beitraege (capital grants), Meliorationen, Projekte zur regionalen Entwicklung (PRE), ' +
9
+ 'Ressourcenprogramme (Art. 77a/77b LwG), Gewaesserschutzprojekte (Art. 62a GSchG), and Starthilfe ' +
10
+ 'Junglandwirte. All amounts in CHF.',
11
+ version: '0.1.0',
12
+ jurisdiction: [...SUPPORTED_JURISDICTIONS],
13
+ data_sources: [
14
+ 'Strukturverbesserungsverordnung (SVV, SR 913.1)',
15
+ 'BLW Weisungen Investitionskredite und Beitraege',
16
+ 'Kantonale Landwirtschaftsaemter',
17
+ 'AGRIDEA Beratungsunterlagen',
18
+ ],
19
+ tools_count: 10,
20
+ links: {
21
+ homepage: 'https://ansvar.eu/open-agriculture',
22
+ repository: 'https://github.com/ansvar-systems/ch-farm-grants-mcp',
23
+ mcp_network: 'https://ansvar.ai/mcp',
24
+ },
25
+ _meta: buildMeta(),
26
+ };
27
+ }
28
+ //# sourceMappingURL=about.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"about.js","sourceRoot":"","sources":["../../src/tools/about.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,IAAI,EAAE,6BAA6B;QACnC,WAAW,EACT,uGAAuG;YACvG,+GAA+G;YAC/G,gGAAgG;YAChG,mGAAmG;YACnG,oCAAoC;QACtC,OAAO,EAAE,OAAO;QAChB,YAAY,EAAE,CAAC,GAAG,uBAAuB,CAAC;QAC1C,YAAY,EAAE;YACZ,iDAAiD;YACjD,iDAAiD;YACjD,iCAAiC;YACjC,6BAA6B;SAC9B;QACD,WAAW,EAAE,EAAE;QACf,KAAK,EAAE;YACL,QAAQ,EAAE,oCAAoC;YAC9C,UAAU,EAAE,sDAAsD;YAClE,WAAW,EAAE,uBAAuB;SACrC;QACD,KAAK,EAAE,SAAS,EAAE;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { Database } from '../db.js';
2
+ interface EligibilityArgs {
3
+ farm_type: string;
4
+ investment_type?: string;
5
+ zone?: string;
6
+ jurisdiction?: string;
7
+ }
8
+ export declare function handleCheckEligibility(db: Database, args: EligibilityArgs): {
9
+ error: string;
10
+ supported: readonly string[];
11
+ message: string;
12
+ } | {
13
+ farm_type: string;
14
+ investment_type: string | null;
15
+ zone: string | null;
16
+ jurisdiction: "CH";
17
+ eligible_grants_count: number;
18
+ eligible_grants: {
19
+ id: string;
20
+ name: string;
21
+ grant_type: string;
22
+ description: string;
23
+ federal_rate_pct: number;
24
+ max_amount: number;
25
+ duration_years: number;
26
+ requirements: string[];
27
+ }[];
28
+ _meta: import("../metadata.js").Meta;
29
+ };
30
+ export {};
31
+ //# sourceMappingURL=check-eligibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-eligibility.d.ts","sourceRoot":"","sources":["../../src/tools/check-eligibility.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,UAAU,eAAe;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe;;;;;;;;;;;YAkClE,MAAM;cAAQ,MAAM;oBAAc,MAAM;qBAAe,MAAM;0BAC/C,MAAM;oBAAc,MAAM;wBAAkB,MAAM;sBACtD,MAAM,EAAE;;;EAiCzB"}
@@ -0,0 +1,57 @@
1
+ import { buildMeta } from '../metadata.js';
2
+ import { validateJurisdiction } from '../jurisdiction.js';
3
+ export function handleCheckEligibility(db, args) {
4
+ const jv = validateJurisdiction(args.jurisdiction);
5
+ if (!jv.valid)
6
+ return jv.error;
7
+ let sql = `
8
+ SELECT DISTINCT g.id, g.name, g.grant_type, g.description, g.federal_rate_pct,
9
+ g.max_amount, g.duration_years, e.requirement, e.farm_type, e.investment_type, e.zone
10
+ FROM eligibility_rules e
11
+ JOIN grants g ON e.grant_id = g.id
12
+ WHERE g.jurisdiction = ?
13
+ AND (LOWER(e.farm_type) = LOWER(?) OR e.farm_type IS NULL OR e.farm_type = 'alle')
14
+ `;
15
+ const params = [jv.jurisdiction, args.farm_type];
16
+ if (args.investment_type) {
17
+ sql += ' AND (LOWER(e.investment_type) = LOWER(?) OR e.investment_type IS NULL OR e.investment_type = \'alle\')';
18
+ params.push(args.investment_type);
19
+ }
20
+ if (args.zone) {
21
+ sql += ' AND (LOWER(e.zone) = LOWER(?) OR e.zone IS NULL OR e.zone = \'alle\')';
22
+ params.push(args.zone);
23
+ }
24
+ sql += ' ORDER BY g.grant_type, g.name';
25
+ const rows = db.all(sql, params);
26
+ // Group by grant
27
+ const grantMap = new Map();
28
+ for (const row of rows) {
29
+ if (!grantMap.has(row.id)) {
30
+ grantMap.set(row.id, {
31
+ id: row.id,
32
+ name: row.name,
33
+ grant_type: row.grant_type,
34
+ description: row.description,
35
+ federal_rate_pct: row.federal_rate_pct,
36
+ max_amount: row.max_amount,
37
+ duration_years: row.duration_years,
38
+ requirements: [],
39
+ });
40
+ }
41
+ const entry = grantMap.get(row.id);
42
+ if (row.requirement && !entry.requirements.includes(row.requirement)) {
43
+ entry.requirements.push(row.requirement);
44
+ }
45
+ }
46
+ const eligible = Array.from(grantMap.values());
47
+ return {
48
+ farm_type: args.farm_type,
49
+ investment_type: args.investment_type ?? null,
50
+ zone: args.zone ?? null,
51
+ jurisdiction: jv.jurisdiction,
52
+ eligible_grants_count: eligible.length,
53
+ eligible_grants: eligible,
54
+ _meta: buildMeta(),
55
+ };
56
+ }
57
+ //# sourceMappingURL=check-eligibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-eligibility.js","sourceRoot":"","sources":["../../src/tools/check-eligibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAU1D,MAAM,UAAU,sBAAsB,CAAC,EAAY,EAAE,IAAqB;IACxE,MAAM,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnD,IAAI,CAAC,EAAE,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC,KAAK,CAAC;IAE/B,IAAI,GAAG,GAAG;;;;;;;GAOT,CAAC;IACF,MAAM,MAAM,GAAc,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAE5D,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,GAAG,IAAI,yGAAyG,CAAC;QACjH,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,GAAG,IAAI,wEAAwE,CAAC;QAChF,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAED,GAAG,IAAI,gCAAgC,CAAC;IAExC,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAIhB,GAAG,EAAE,MAAM,CAAC,CAAC;IAEhB,iBAAiB;IACjB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAIpB,CAAC;IAEL,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE;gBACnB,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;gBACtC,UAAU,EAAE,GAAG,CAAC,UAAU;gBAC1B,cAAc,EAAE,GAAG,CAAC,cAAc;gBAClC,YAAY,EAAE,EAAE;aACjB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;QACpC,IAAI,GAAG,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YACrE,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAE/C,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,IAAI;QAC7C,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;QACvB,YAAY,EAAE,EAAE,CAAC,YAAY;QAC7B,qBAAqB,EAAE,QAAQ,CAAC,MAAM;QACtC,eAAe,EAAE,QAAQ;QACzB,KAAK,EAAE,SAAS,EAAE;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { buildMeta } from '../metadata.js';
2
+ import type { Database } from '../db.js';
3
+ interface FreshnessResult {
4
+ status: 'fresh' | 'stale' | 'unknown';
5
+ last_ingest: string | null;
6
+ build_date: string | null;
7
+ schema_version: string | null;
8
+ days_since_ingest: number | null;
9
+ staleness_threshold_days: number;
10
+ refresh_command: string;
11
+ _meta: ReturnType<typeof buildMeta>;
12
+ }
13
+ export declare function handleCheckFreshness(db: Database): FreshnessResult;
14
+ export {};
15
+ //# sourceMappingURL=check-freshness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-freshness.d.ts","sourceRoot":"","sources":["../../src/tools/check-freshness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,UAAU,eAAe;IACvB,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACtC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,wBAAwB,EAAE,MAAM,CAAC;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;CACrC;AAID,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,QAAQ,GAAG,eAAe,CAyBlE"}
@@ -0,0 +1,26 @@
1
+ import { buildMeta } from '../metadata.js';
2
+ const STALENESS_THRESHOLD_DAYS = 90;
3
+ export function handleCheckFreshness(db) {
4
+ const lastIngest = db.get('SELECT value FROM db_metadata WHERE key = ?', ['last_ingest']);
5
+ const buildDate = db.get('SELECT value FROM db_metadata WHERE key = ?', ['build_date']);
6
+ const schemaVersion = db.get('SELECT value FROM db_metadata WHERE key = ?', ['schema_version']);
7
+ let status = 'unknown';
8
+ let daysSinceIngest = null;
9
+ if (lastIngest?.value) {
10
+ const ingestDate = new Date(lastIngest.value);
11
+ const now = new Date();
12
+ daysSinceIngest = Math.floor((now.getTime() - ingestDate.getTime()) / (1000 * 60 * 60 * 24));
13
+ status = daysSinceIngest <= STALENESS_THRESHOLD_DAYS ? 'fresh' : 'stale';
14
+ }
15
+ return {
16
+ status,
17
+ last_ingest: lastIngest?.value ?? null,
18
+ build_date: buildDate?.value ?? null,
19
+ schema_version: schemaVersion?.value ?? null,
20
+ days_since_ingest: daysSinceIngest,
21
+ staleness_threshold_days: STALENESS_THRESHOLD_DAYS,
22
+ refresh_command: 'gh workflow run ingest.yml -R ansvar-systems/ch-farm-grants-mcp',
23
+ _meta: buildMeta(),
24
+ };
25
+ }
26
+ //# sourceMappingURL=check-freshness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-freshness.js","sourceRoot":"","sources":["../../src/tools/check-freshness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAc3C,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAEpC,MAAM,UAAU,oBAAoB,CAAC,EAAY;IAC/C,MAAM,UAAU,GAAG,EAAE,CAAC,GAAG,CAAoB,6CAA6C,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAC7G,MAAM,SAAS,GAAG,EAAE,CAAC,GAAG,CAAoB,6CAA6C,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3G,MAAM,aAAa,GAAG,EAAE,CAAC,GAAG,CAAoB,6CAA6C,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAEnH,IAAI,MAAM,GAAkC,SAAS,CAAC;IACtD,IAAI,eAAe,GAAkB,IAAI,CAAC;IAE1C,IAAI,UAAU,EAAE,KAAK,EAAE,CAAC;QACtB,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAC7F,MAAM,GAAG,eAAe,IAAI,wBAAwB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAC3E,CAAC;IAED,OAAO;QACL,MAAM;QACN,WAAW,EAAE,UAAU,EAAE,KAAK,IAAI,IAAI;QACtC,UAAU,EAAE,SAAS,EAAE,KAAK,IAAI,IAAI;QACpC,cAAc,EAAE,aAAa,EAAE,KAAK,IAAI,IAAI;QAC5C,iBAAiB,EAAE,eAAe;QAClC,wBAAwB,EAAE,wBAAwB;QAClD,eAAe,EAAE,iEAAiE;QAClF,KAAK,EAAE,SAAS,EAAE;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { Database } from '../db.js';
2
+ interface DeadlineArgs {
3
+ grant_id?: string;
4
+ canton?: string;
5
+ jurisdiction?: string;
6
+ }
7
+ export declare function handleGetApplicationDeadlines(db: Database, args: DeadlineArgs): {
8
+ error: string;
9
+ supported: readonly string[];
10
+ message: string;
11
+ } | {
12
+ grant_id: string | null;
13
+ canton: string | null;
14
+ jurisdiction: "CH";
15
+ deadlines_count: number;
16
+ deadlines: {
17
+ grant_id: string;
18
+ grant_name: string;
19
+ grant_type: string;
20
+ canton: string;
21
+ deadline_date: string;
22
+ notes: string;
23
+ }[];
24
+ _meta: import("../metadata.js").Meta;
25
+ };
26
+ export {};
27
+ //# sourceMappingURL=get-application-deadlines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-application-deadlines.d.ts","sourceRoot":"","sources":["../../src/tools/get-application-deadlines.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,UAAU,YAAY;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,6BAA6B,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY;;;;;;;;;;;;;;;;;;EA4C7E"}
@@ -0,0 +1,40 @@
1
+ import { buildMeta } from '../metadata.js';
2
+ import { validateJurisdiction } from '../jurisdiction.js';
3
+ export function handleGetApplicationDeadlines(db, args) {
4
+ const jv = validateJurisdiction(args.jurisdiction);
5
+ if (!jv.valid)
6
+ return jv.error;
7
+ let sql = `
8
+ SELECT d.*, g.name as grant_name, g.grant_type
9
+ FROM application_deadlines d
10
+ JOIN grants g ON d.grant_id = g.id
11
+ WHERE g.jurisdiction = ?
12
+ `;
13
+ const params = [jv.jurisdiction];
14
+ if (args.grant_id) {
15
+ sql += ' AND (d.grant_id = ? OR LOWER(g.name) = LOWER(?))';
16
+ params.push(args.grant_id, args.grant_id);
17
+ }
18
+ if (args.canton) {
19
+ sql += ' AND (UPPER(d.canton) = UPPER(?) OR d.canton IS NULL OR d.canton = \'alle\')';
20
+ params.push(args.canton);
21
+ }
22
+ sql += ' ORDER BY d.deadline_date, g.name';
23
+ const deadlines = db.all(sql, params);
24
+ return {
25
+ grant_id: args.grant_id ?? null,
26
+ canton: args.canton ?? null,
27
+ jurisdiction: jv.jurisdiction,
28
+ deadlines_count: deadlines.length,
29
+ deadlines: deadlines.map(d => ({
30
+ grant_id: d.grant_id,
31
+ grant_name: d.grant_name,
32
+ grant_type: d.grant_type,
33
+ canton: d.canton,
34
+ deadline_date: d.deadline_date,
35
+ notes: d.notes,
36
+ })),
37
+ _meta: buildMeta(),
38
+ };
39
+ }
40
+ //# sourceMappingURL=get-application-deadlines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-application-deadlines.js","sourceRoot":"","sources":["../../src/tools/get-application-deadlines.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAS1D,MAAM,UAAU,6BAA6B,CAAC,EAAY,EAAE,IAAkB;IAC5E,MAAM,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnD,IAAI,CAAC,EAAE,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC,KAAK,CAAC;IAE/B,IAAI,GAAG,GAAG;;;;;GAKT,CAAC;IACF,MAAM,MAAM,GAAc,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;IAE5C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,GAAG,IAAI,mDAAmD,CAAC;QAC3D,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,GAAG,IAAI,8EAA8E,CAAC;QACtF,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED,GAAG,IAAI,mCAAmC,CAAC;IAE3C,MAAM,SAAS,GAAG,EAAE,CAAC,GAAG,CAGrB,GAAG,EAAE,MAAM,CAAC,CAAC;IAEhB,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI;QAC/B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI;QAC3B,YAAY,EAAE,EAAE,CAAC,YAAY;QAC7B,eAAe,EAAE,SAAS,CAAC,MAAM;QACjC,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC7B,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,aAAa,EAAE,CAAC,CAAC,aAAa;YAC9B,KAAK,EAAE,CAAC,CAAC,KAAK;SACf,CAAC,CAAC;QACH,KAAK,EAAE,SAAS,EAAE;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { Database } from '../db.js';
2
+ interface GrantDetailsArgs {
3
+ grant_id: string;
4
+ jurisdiction?: string;
5
+ }
6
+ export declare function handleGetGrantDetails(db: Database, args: GrantDetailsArgs): {
7
+ error: string;
8
+ supported: readonly string[];
9
+ message: string;
10
+ } | {
11
+ error: string;
12
+ message: string;
13
+ } | {
14
+ zone_bonus: any;
15
+ options: {
16
+ option_name: string;
17
+ description: string;
18
+ rate: string;
19
+ conditions: string;
20
+ }[];
21
+ eligibility_rules: {
22
+ farm_type: string;
23
+ investment_type: string;
24
+ zone: string;
25
+ requirement: string;
26
+ }[];
27
+ _meta: import("../metadata.js").Meta;
28
+ id: string;
29
+ name: string;
30
+ grant_type: string;
31
+ description: string;
32
+ federal_rate_pct: number;
33
+ max_amount: number;
34
+ duration_years: number;
35
+ legal_basis: string;
36
+ language: string;
37
+ jurisdiction: string;
38
+ error?: undefined;
39
+ message?: undefined;
40
+ };
41
+ export {};
42
+ //# sourceMappingURL=get-grant-details.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-grant-details.d.ts","sourceRoot":"","sources":["../../src/tools/get-grant-details.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB;;;;;;;;;;qBAqBzD,MAAM;qBAAe,MAAM;cAAQ,MAAM;oBAAc,MAAM;;;mBAO/D,MAAM;yBAAmB,MAAM;cAAQ,MAAM;qBAAe,MAAM;;;QAvBzE,MAAM;UAAQ,MAAM;gBAAc,MAAM;iBAAe,MAAM;sBAC/C,MAAM;gBAAc,MAAM;oBAAkB,MAAM;iBACnC,MAAM;cAAY,MAAM;kBAAgB,MAAM;;;EAkClF"}
@@ -0,0 +1,24 @@
1
+ import { buildMeta } from '../metadata.js';
2
+ import { validateJurisdiction } from '../jurisdiction.js';
3
+ export function handleGetGrantDetails(db, args) {
4
+ const jv = validateJurisdiction(args.jurisdiction);
5
+ if (!jv.valid)
6
+ return jv.error;
7
+ const grant = db.get('SELECT * FROM grants WHERE (id = ? OR LOWER(name) = LOWER(?)) AND jurisdiction = ?', [args.grant_id, args.grant_id, jv.jurisdiction]);
8
+ if (!grant) {
9
+ return {
10
+ error: 'not_found',
11
+ message: `Grant '${args.grant_id}' not found. Use search_grants to find available grant programmes.`,
12
+ };
13
+ }
14
+ const options = db.all('SELECT option_name, description, rate, conditions FROM grant_options WHERE grant_id = ?', [grant.id]);
15
+ const eligibility = db.all('SELECT farm_type, investment_type, zone, requirement FROM eligibility_rules WHERE grant_id = ?', [grant.id]);
16
+ return {
17
+ ...grant,
18
+ zone_bonus: grant.zone_bonus ? JSON.parse(grant.zone_bonus) : null,
19
+ options: options.length > 0 ? options : [],
20
+ eligibility_rules: eligibility.length > 0 ? eligibility : [],
21
+ _meta: buildMeta(),
22
+ };
23
+ }
24
+ //# sourceMappingURL=get-grant-details.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-grant-details.js","sourceRoot":"","sources":["../../src/tools/get-grant-details.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAQ1D,MAAM,UAAU,qBAAqB,CAAC,EAAY,EAAE,IAAsB;IACxE,MAAM,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACnD,IAAI,CAAC,EAAE,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC,KAAK,CAAC;IAE/B,MAAM,KAAK,GAAG,EAAE,CAAC,GAAG,CAKlB,oFAAoF,EACpF,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,CAChD,CAAC;IAEF,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,UAAU,IAAI,CAAC,QAAQ,oEAAoE;SACrG,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,CAGpB,yFAAyF,EACzF,CAAC,KAAK,CAAC,EAAE,CAAC,CACX,CAAC;IAEF,MAAM,WAAW,GAAG,EAAE,CAAC,GAAG,CAGxB,gGAAgG,EAChG,CAAC,KAAK,CAAC,EAAE,CAAC,CACX,CAAC;IAEF,OAAO;QACL,GAAG,KAAK;QACR,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI;QAClE,OAAO,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QAC1C,iBAAiB,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE;QAC5D,KAAK,EAAE,SAAS,EAAE;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { Database } from '../db.js';
2
+ interface PaymentRatesArgs {
3
+ grant_id: string;
4
+ zone?: string;
5
+ jurisdiction?: string;
6
+ }
7
+ export declare function handleGetPaymentRates(db: Database, args: PaymentRatesArgs): {
8
+ error: string;
9
+ supported: readonly string[];
10
+ message: string;
11
+ } | {
12
+ error: string;
13
+ message: string;
14
+ grant_id?: undefined;
15
+ grant_name?: undefined;
16
+ grant_type?: undefined;
17
+ federal_rate_pct?: undefined;
18
+ max_amount_chf?: undefined;
19
+ duration_years?: undefined;
20
+ zone_requested?: undefined;
21
+ zone_bonus?: undefined;
22
+ all_zone_bonuses?: undefined;
23
+ rate_options?: undefined;
24
+ jurisdiction?: undefined;
25
+ currency?: undefined;
26
+ _meta?: undefined;
27
+ } | {
28
+ grant_id: string;
29
+ grant_name: string;
30
+ grant_type: string;
31
+ federal_rate_pct: number;
32
+ max_amount_chf: number;
33
+ duration_years: number;
34
+ zone_requested: string | null;
35
+ zone_bonus: string | null;
36
+ all_zone_bonuses: Record<string, string> | null;
37
+ rate_options: {
38
+ option_name: string;
39
+ rate: string;
40
+ conditions: string;
41
+ }[];
42
+ jurisdiction: "CH";
43
+ currency: string;
44
+ _meta: import("../metadata.js").Meta;
45
+ error?: undefined;
46
+ message?: undefined;
47
+ };
48
+ export {};
49
+ //# sourceMappingURL=get-payment-rates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-payment-rates.d.ts","sourceRoot":"","sources":["../../src/tools/get-payment-rates.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA4BzD,MAAM;cAAQ,MAAM;oBAAc,MAAM;;;;;;;EAqBxD"}