@reneturcios/fiscocheck 0.0.0-stage → 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rene Turcios
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,160 @@
1
- # Temporary Holding Version
1
+ # fiscocheck
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ fiscocheck is a small local bridge to the hosted
4
+ imperioutils fisco-it MCP server, a collection of
5
+ Italian tax utilities. Through it an agent can check
6
+ and generate a codice fiscale, validate a partita
7
+ IVA, an IBAN or a PEC address, look up a CAP or an
8
+ ATECO code, run the common calculations (regime
9
+ forfettario, IVA, reverse charge, split payment,
10
+ IMU), parse a FatturaPA document, compose the rows
11
+ of an F24 form from amounts the caller has already
12
+ calculated, work through Intrastat periodicity and
13
+ composition, read NIS2 reference data, verify a
14
+ payee, and run the guardian supplier checks. The
15
+ tool descriptions upstream are in Italian and this
16
+ bridge serves them exactly as captured, untranslated.
17
+
18
+ The bridge holds no tax tables of its own. It
19
+ answers the tool list locally, exactly as captured
20
+ from the live endpoint, and forwards each tool call
21
+ upstream, returning whatever comes back untouched.
22
+ No tool in this surface submits a filing or executes
23
+ a payment: the F24 and Intrastat composers assemble
24
+ documents from caller-supplied rows, and the
25
+ guardian tools check caller-supplied supplier data
26
+ (IBAN, partita IVA and codice fiscale checksums, and
27
+ the EU VIES public register).
28
+
29
+ ## Tools
30
+
31
+ 28 tools, grouped by area:
32
+
33
+ - Identifiers: `validate_codice_fiscale`,
34
+ `generate_codice_fiscale`, `validate_partita_iva`,
35
+ `validate_iban`, `validate_pec`.
36
+ - Lookups: `lookup_cap`, `lookup_ateco`,
37
+ `search_ateco`.
38
+ - Calculations: `calc_forfettario`, `calc_iva`,
39
+ `calc_reverse_charge`, `calc_split_payment`,
40
+ `calc_imu`.
41
+ - Documents: `parse_fatturapa`,
42
+ `parse_verify_fatturapa`, `compose_f24`.
43
+ - Intrastat: `intrastat_periodicity`,
44
+ `intrastat_compose`, `intrastat_reference`.
45
+ - NIS2: `nis2_tipologie`, `nis2_ambito`,
46
+ `nis2_reference`.
47
+ - Payee and guardian: `verify_payee`,
48
+ `guardian_list_suppliers`,
49
+ `guardian_supplier_ledger`,
50
+ `guardian_supplier_status`, `guardian_check_iban`,
51
+ `guardian_watch_supplier`.
52
+
53
+ Five tools (`calc_imu`, `intrastat_reference`,
54
+ `nis2_tipologie`, `nis2_reference`, `verify_payee`)
55
+ were captured with an empty `required: []` list, and
56
+ three guardian tools (`guardian_list_suppliers`,
57
+ `guardian_supplier_ledger`,
58
+ `guardian_supplier_status`) were captured with no
59
+ `required` key at all; both shapes are served
60
+ verbatim. Per the original registry record, 23 tools
61
+ are free and the 5 guardian tools are the keyed set.
62
+
63
+ ## Configuration
64
+
65
+ - `IMPERIOUTILS_MCP_URL` (optional) — override the
66
+ upstream endpoint. Defaults to
67
+ `https://imperioutils.com/api/mcp`. (The override
68
+ hook is this rebuild's own labelled reconstruction.)
69
+ - `IMPERIOUTILS_API_KEY` (optional) — when set, every
70
+ upstream request carries an `X-API-Key: <key>`
71
+ header, for the caller's own imperioutils API key.
72
+ When it is not set, no key header is sent. (The
73
+ header name is pinned by the original's registry
74
+ record; the record pins no package env name, so
75
+ forwarding the key from this env var is a labelled
76
+ reconstruction — the original surface was captured
77
+ keyless.)
78
+
79
+ ### Forwarding mechanics
80
+
81
+ On the first tool call the client opens a streamable
82
+ HTTP session upstream: a JSON-RPC `initialize`
83
+ request (protocolVersion `2025-03-26`, clientInfo
84
+ name `fiscocheck`), then a
85
+ `notifications/initialized` notification, then the
86
+ `tools/call` request carrying the caller's arguments
87
+ unchanged. When the upstream answers `initialize`
88
+ with an `Mcp-Session-Id` header, that value rides on
89
+ every later request of the session, which is reused
90
+ for the life of the process. Replies may arrive as
91
+ plain JSON or as server-sent events; both are read.
92
+
93
+ Successful upstream results pass through verbatim,
94
+ including any `isError` flag the upstream sets.
95
+ Failures — a JSON-RPC error, a non-2xx status, an
96
+ unreadable response, or a request that cannot be
97
+ completed — come back as an `isError` result whose
98
+ text starts with `fiscocheck error:` (this rendering
99
+ is this rebuild's own labelled reconstruction).
100
+
101
+ ## CLI
102
+
103
+ Each tool is also a subcommand taking one JSON
104
+ argument string:
105
+
106
+ ```bash
107
+ npx @reneturcios/fiscocheck validate_iban '{"iban":"IT60X0542811101000000123456"}'
108
+ npx @reneturcios/fiscocheck validate_codice_fiscale '{"codice_fiscale":"RSSMRA80A01H501U"}'
109
+ npx @reneturcios/fiscocheck calc_imu '{}'
110
+ npx @reneturcios/fiscocheck --version
111
+ ```
112
+
113
+ Exit codes: `0` on success, `1` on an `isError`
114
+ result, `2` on a usage error.
115
+
116
+ ## MCP server
117
+
118
+ ```bash
119
+ npx -y @reneturcios/fiscocheck mcp
120
+ ```
121
+
122
+ MCP client config:
123
+
124
+ ```json
125
+ {
126
+ "mcpServers": {
127
+ "fiscocheck": {
128
+ "command": "npx",
129
+ "args": ["-y", "@reneturcios/fiscocheck", "mcp"]
130
+ }
131
+ }
132
+ }
133
+ ```
134
+
135
+ ## Docker
136
+
137
+ ```bash
138
+ docker run -i ghcr.io/cloudcorprecords/fiscocheck
139
+ docker run --rm ghcr.io/cloudcorprecords/fiscocheck --version
140
+ ```
141
+
142
+ The container's default command is `mcp`, so the first
143
+ form is a stdio MCP server; any other arguments reach
144
+ the CLI normally.
145
+
146
+ ## Development
147
+
148
+ ```bash
149
+ npm install
150
+ npm run build
151
+ npm test
152
+ npm run dev
153
+ ```
154
+
155
+ The test suite runs entirely against a stubbed
156
+ JSON-RPC upstream — no live network calls.
157
+
158
+ ## License
159
+
160
+ MIT — see `LICENSE`.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * fiscocheck CLI.
4
+ *
5
+ * fiscocheck <tool> '<json-args>'
6
+ * fiscocheck mcp
7
+ * fiscocheck --version
8
+ *
9
+ * <tool> is one of the 28 forwarded tools. Each tool
10
+ * subcommand takes a single JSON argument string holding
11
+ * that tool's arguments, forwards the call the same way
12
+ * the MCP path does, and prints the forwarded result
13
+ * content. Exit codes: 0 success, 1 on an isError
14
+ * result, 2 usage error.
15
+ */
16
+ import { callTool, TOOL_NAMES, VERSION } from "./forward.js";
17
+ function usage() {
18
+ console.error(`Usage:
19
+ fiscocheck <tool> '<json-args>' one of: ${TOOL_NAMES.join(", ")}
20
+ fiscocheck mcp
21
+ fiscocheck --version`);
22
+ process.exit(2);
23
+ }
24
+ function firstText(result) {
25
+ const content = result.content;
26
+ if (Array.isArray(content)) {
27
+ for (const item of content) {
28
+ if (item !== null &&
29
+ typeof item === "object" &&
30
+ item.type === "text" &&
31
+ typeof item.text === "string") {
32
+ return item.text;
33
+ }
34
+ }
35
+ }
36
+ return typeof content === "string" ? content : JSON.stringify(content);
37
+ }
38
+ async function main() {
39
+ const [cmd, ...rest] = process.argv.slice(2);
40
+ if (cmd === "--version" || cmd === "-v") {
41
+ console.log(VERSION);
42
+ return;
43
+ }
44
+ if (cmd === "mcp") {
45
+ if (rest.length !== 0)
46
+ usage();
47
+ const { startMcpServer } = await import("./mcp.js");
48
+ await startMcpServer();
49
+ return;
50
+ }
51
+ if (!TOOL_NAMES.includes(cmd ?? ""))
52
+ usage();
53
+ if (rest.length > 1)
54
+ usage();
55
+ let args = {};
56
+ if (rest.length === 1) {
57
+ try {
58
+ const parsed = JSON.parse(rest[0]);
59
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
60
+ usage();
61
+ }
62
+ args = parsed;
63
+ }
64
+ catch {
65
+ console.error("error: argument must be a JSON object string");
66
+ process.exit(2);
67
+ }
68
+ }
69
+ const result = await callTool(cmd, args);
70
+ if (result.isError) {
71
+ console.error(`error: ${firstText(result)}`);
72
+ process.exit(1);
73
+ }
74
+ console.log(typeof result.content === "string"
75
+ ? result.content
76
+ : JSON.stringify(result.content, null, 2));
77
+ }
78
+ void main();
79
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * fiscocheck core: a forwarding client for the hosted
3
+ * imperioutils fisco-it MCP server (Italian tax tools).
4
+ *
5
+ * Nothing is computed locally. tools/list is answered
6
+ * from the literal definitions below, taken verbatim
7
+ * from a live capture of the upstream server (name,
8
+ * title, description and inputSchema exactly as
9
+ * captured, title key included; descriptions are in
10
+ * Italian and are served verbatim, not translated).
11
+ * A tools/call travels upstream over a streamable-HTTP
12
+ * JSON-RPC session: an initialize POST, a
13
+ * notifications/initialized POST, then the tools/call
14
+ * POST, carrying the Mcp-Session-Id response header on
15
+ * later requests when the upstream issues one. The
16
+ * session opens lazily on the first forwarded call and
17
+ * is reused for the client's life.
18
+ *
19
+ * The endpoint is pinned to
20
+ * https://imperioutils.com/api/mcp and may be replaced
21
+ * with the IMPERIOUTILS_MCP_URL environment variable
22
+ * (that override is a labelled reconstruction). When
23
+ * IMPERIOUTILS_API_KEY is set, every upstream request
24
+ * carries an `X-API-Key: <key>` header (header name
25
+ * pinned by the registry record's remote declaration;
26
+ * forwarding the key from this env var is a labelled
27
+ * reconstruction, as the capture was taken keyless and
28
+ * the record pins no package env name). When it is
29
+ * unset, no key header goes out.
30
+ *
31
+ * A successful upstream result is returned exactly as
32
+ * received, isError flag and extra fields included.
33
+ * Failures — an upstream JSON-RPC error, a non-2xx
34
+ * status, a body that cannot be parsed, or a fetch that
35
+ * throws or times out — become an isError result whose
36
+ * text begins with `fiscocheck error:` (that rendering
37
+ * is a labelled reconstruction). Replies may be plain
38
+ * JSON or SSE (`data:` lines); the JSON-RPC message
39
+ * whose id matches the request wins.
40
+ */
41
+ import type { ForwardDeps, ToolArgs, ToolDef, ToolResult } from "./types.js";
42
+ export declare const VERSION = "0.1.0";
43
+ export declare const DEFAULT_ENDPOINT_URL = "https://imperioutils.com/api/mcp";
44
+ export declare const DEFAULT_TIMEOUT_MS = 30000;
45
+ export declare const PROTOCOL_VERSION = "2025-03-26";
46
+ export declare const TOOL_DEFS: ToolDef[];
47
+ export declare const TOOL_NAMES: string[];
48
+ /** Whether `name` belongs to the captured surface. */
49
+ export declare function isKnownTool(name: string): boolean;
50
+ /**
51
+ * Read a JSON-RPC response body, tolerating SSE framing.
52
+ * Returns the message whose id matches `expectedId` when
53
+ * present, otherwise the last parseable message, otherwise
54
+ * null when nothing in the body parses.
55
+ */
56
+ export declare function parseRpcBody(text: string, expectedId?: number): Record<string, unknown> | null;
57
+ /**
58
+ * A forwarding client that holds a single upstream
59
+ * session, opened lazily on first use and reused from
60
+ * then on (for the process lifetime in the MCP server,
61
+ * or for a single invocation in the CLI).
62
+ */
63
+ export declare class FiscocheckClient {
64
+ private readonly deps;
65
+ private sessionId;
66
+ private ready;
67
+ private sessionPromise;
68
+ private idCounter;
69
+ constructor(deps?: ForwardDeps);
70
+ private fetchFn;
71
+ private endpointUrl;
72
+ private apiKey;
73
+ private timeoutMs;
74
+ private nextId;
75
+ private post;
76
+ private ensureSession;
77
+ /** Forward one tool call; upstream failures come back as isError results. */
78
+ callTool(name: string, args: ToolArgs): Promise<ToolResult>;
79
+ }
80
+ /** Build a forwarding client; tests inject a fake fetch and env through deps. */
81
+ export declare function createClient(deps?: ForwardDeps): FiscocheckClient;
82
+ /** One-shot helper: a fresh client for a single call (the CLI path). */
83
+ export declare function callTool(name: string, args: ToolArgs, deps?: ForwardDeps): Promise<ToolResult>;