@toolstop/export-control
Advanced tools
+31
-0
@@ -112,2 +112,30 @@ // Licence-requirement lookup against the Commerce Country Chart. | ||
| /** | ||
| * An entry with no controls in the data is a question this server cannot | ||
| * answer, and it must never come back as `licenseRequired: false`. | ||
| * | ||
| * Two different things produce one: an entry whose licence requirements are | ||
| * written as prose rather than as a country-chart table (0A983 reads "a license | ||
| * is required for ALL destinations", which is the opposite of no licence), and | ||
| * an entry that is a pointer to the ITAR and carries no EAR requirement at all | ||
| * (0A002). Both are real, controlled items. Neither can be answered from an | ||
| * empty control list, and `false` computed from an empty array is not a finding | ||
| * about the regulation, it is the absence of one. | ||
| */ | ||
| function indeterminateResult(eccn, entry) { | ||
| return { | ||
| status: "indeterminate", | ||
| eccn, | ||
| title: entry.t, | ||
| reasons: (entry.r ?? []).map((r) => ({ code: r, name: REASON_CODES[r] ?? null })), | ||
| message: | ||
| `${eccn} carries no country-chart control in the ${SOURCE_EDITION} data, so the chart cannot ` + | ||
| "answer for it. Do not read this as no licence required: entries in this state include items " + | ||
| "requiring a licence to all destinations, and items that are subject to the ITAR rather than " + | ||
| "the EAR. Read the entry directly in 15 CFR part 774, Supplement No. 1, and check the title " + | ||
| "returned here, which often states the requirement.", | ||
| notCovered: NOT_COVERED, | ||
| }; | ||
| } | ||
| /** Every caveat that a chart answer does not cover. Attached to every result. */ | ||
@@ -172,2 +200,4 @@ const NOT_COVERED = [ | ||
| if (!entry.c.length) return indeterminateResult(eccn, entry); | ||
| const marks = new Set(row.c); | ||
@@ -204,2 +234,3 @@ const triggered = []; | ||
| if (!e) return { status: "unknown_eccn", eccn, message: `${eccn} is not in the ${SOURCE_EDITION} Commerce Control List.` }; | ||
| if (!e.c.length) return { ...indeterminateResult(eccn, e), chartDetermined: false, sourceEdition: SOURCE_EDITION }; | ||
| return { | ||
@@ -206,0 +237,0 @@ status: "ok", |
+31
-6
@@ -15,2 +15,3 @@ // The single source of truth for this server. Both transports import this and | ||
| "embargoed", | ||
| "indeterminate", | ||
| "invalid_eccn", | ||
@@ -28,4 +29,6 @@ "unknown_eccn", | ||
| "Outcome of the lookup. Only `ok` carries an answer. `embargoed` means the " + | ||
| "chart does not govern the destination. `ambiguous_country` means the name " + | ||
| "matched more than one row and you must ask which was meant.", | ||
| "chart does not govern the destination. `indeterminate` means the entry has " + | ||
| "no country-chart control in this data and the chart cannot answer for it, " + | ||
| "which is not the same as no licence being required. `ambiguous_country` " + | ||
| "means the name matched more than one row and you must ask which was meant.", | ||
| }; | ||
@@ -35,3 +38,3 @@ | ||
| name: "export-control", | ||
| version: "0.1.0", | ||
| version: "0.2.0", | ||
| instructions: | ||
@@ -62,2 +65,9 @@ "Answers one question: does the Commerce Country Chart require an export " + | ||
| "you should put that choice to a human rather than picking.\n\n" + | ||
| "Some entries write their licence requirement as prose rather than as a " + | ||
| "chart column, and some are pointers to the ITAR carrying no EAR " + | ||
| "requirement at all. Those return `indeterminate` rather than an answer, " + | ||
| "because a chart verdict computed from an entry with no chart controls " + | ||
| "would read as `licenseRequired: false` for items that in fact require a " + | ||
| "licence to every destination. Treat `indeterminate` as unanswered and go " + | ||
| "to the regulation.\n\n" + | ||
| "A result of `licenseRequired: false` means only that the country chart " + | ||
@@ -87,4 +97,6 @@ "does not require one for that ECCN. It is not permission to export. The " + | ||
| "about the Entity List, embargoes, end-use controls, or whether the " + | ||
| "ECCN is the right one. This tool cannot classify an item into an " + | ||
| "ECCN and will not try.", | ||
| "ECCN is the right one. Entries whose requirement is not written as a " + | ||
| "chart column return `indeterminate` instead of a verdict, and that is " + | ||
| "an unanswered question rather than a negative answer. This tool cannot " + | ||
| "classify an item into an ECCN and will not try.", | ||
| annotations: { readOnlyHint: true, openWorldHint: false }, | ||
@@ -140,2 +152,4 @@ inputSchema: { | ||
| }, | ||
| title: { type: "string", description: "The Control List entry heading, on an indeterminate result." }, | ||
| message: { type: "string", description: "Why no verdict was returned, when status is not `ok`." }, | ||
| }, | ||
@@ -150,2 +164,8 @@ required: ["status"], | ||
| { | ||
| // The requirement is "a license is required for ALL destinations", | ||
| // written as prose. An empty control list must not become `false`. | ||
| args: { eccn: "0A983", country: "France" }, | ||
| expect: { status: "indeterminate", eccn: "0A983" }, | ||
| }, | ||
| { | ||
| args: { eccn: "3A001", country: "Canada" }, | ||
@@ -180,3 +200,4 @@ expect: { status: "ok", licenseRequired: false }, | ||
| "decided by the country chart at all, and those return " + | ||
| "`chartDetermined: false` with the requirement text instead. Knowing an " + | ||
| "`chartDetermined: false` with the requirement text instead, or " + | ||
| "`indeterminate` when the entry carries no chart control at all. Knowing an " + | ||
| "entry's reasons for control does not tell you whether a licence is " + | ||
@@ -226,2 +247,6 @@ "required for a destination; pass the ECCN to check_export_license for " + | ||
| }, | ||
| { | ||
| args: { eccn: "0A002" }, // present, but a pointer to the ITAR | ||
| expect: { status: "indeterminate", chartDetermined: false }, | ||
| }, | ||
| ], | ||
@@ -228,0 +253,0 @@ handler: ({ eccn }) => lookupEccn(eccn), |
+1
-1
| { | ||
| "name": "@toolstop/export-control", | ||
| "version": "0.1.0", | ||
| "version": "0.2.0", | ||
| "mcpName": "dev.toolstop/export-control", | ||
@@ -5,0 +5,0 @@ "description": "MCP server that answers whether the US Commerce Country Chart requires an export licence for a given ECCN to a given destination, from the published CFR tables.", |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
318725
1.03%1986
2.8%