proofread-mcp 0.1.0 → 0.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.
- package/README.md +31 -19
- package/dist/cli.js +9 -1
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +14 -3
- package/dist/client.js +73 -16
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +8 -4
- package/dist/errors.js +44 -10
- package/dist/errors.js.map +1 -1
- package/dist/format.d.ts +6 -4
- package/dist/format.js +86 -35
- package/dist/format.js.map +1 -1
- package/dist/http.d.ts +8 -1
- package/dist/http.js +43 -10
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +3 -2
- package/dist/server.js.map +1 -1
- package/dist/sse.d.ts +1 -0
- package/dist/sse.js +42 -20
- package/dist/sse.js.map +1 -1
- package/dist/tools/billing_link.d.ts +8 -0
- package/dist/tools/billing_link.js +31 -0
- package/dist/tools/billing_link.js.map +1 -0
- package/dist/tools/check_citations.d.ts +7 -4
- package/dist/tools/check_citations.js +18 -12
- package/dist/tools/check_citations.js.map +1 -1
- package/dist/tools/check_document.js +22 -14
- package/dist/tools/check_document.js.map +1 -1
- package/dist/tools/index.js +3 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/render_report.js +4 -4
- package/dist/tools/render_report.js.map +1 -1
- package/dist/tools/resolve_citation.js +2 -2
- package/dist/tools/resolve_citation.js.map +1 -1
- package/dist/tools/resolve_citations.js +2 -2
- package/dist/tools/resolve_citations.js.map +1 -1
- package/dist/tools/sign_up.d.ts +5 -0
- package/dist/tools/sign_up.js +42 -0
- package/dist/tools/sign_up.js.map +1 -0
- package/dist/tools/tool.d.ts +11 -2
- package/dist/tools/tool.js +20 -7
- package/dist/tools/tool.js.map +1 -1
- package/dist/types.d.ts +19 -0
- package/package.json +2 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { formatReport } from "../format.js";
|
|
3
3
|
import { rememberReport } from "../reports.js";
|
|
4
|
-
import { DEEP_NOTE, LIMITS_NOTE, defineTool, fail, ok, progressReporter } from "./tool.js";
|
|
4
|
+
import { DEEP_NOTE, KEY_NOTE, LIMITS_NOTE, defineTool, fail, ok, progressReporter, publicSummary } from "./tool.js";
|
|
5
5
|
export const checkCitations = defineTool({
|
|
6
6
|
name: "check_citations",
|
|
7
7
|
title: "Check legal citations in text",
|
|
@@ -11,36 +11,42 @@ export const checkCitations = defineTool({
|
|
|
11
11
|
"(red = check this: the register holds something concrete that disagrees, such as a different case at that citation or quoted words not in the opinion; " +
|
|
12
12
|
"orange = cannot verify: nothing to check against, such as a Westlaw/Lexis identifier or a volume newer than the register), " +
|
|
13
13
|
"the number of citations found, and a report id for render_report. " +
|
|
14
|
-
LIMITS_NOTE + " " + DEEP_NOTE + " Free tier: 20 checks a month
|
|
14
|
+
LIMITS_NOTE + " " + DEEP_NOTE + " Free tier: 20 checks a month. " + KEY_NOTE,
|
|
15
15
|
inputSchema: {
|
|
16
16
|
text: z.string().min(1).max(2_000_000).describe("The text to check, as written (paragraphs, footnotes, a whole brief). Pasted text is fine."),
|
|
17
17
|
deep: z.boolean().optional().describe("Also check whether each cited opinion supports the sentence it is cited for. Slower, opt-in, 3 per month on the free tier."),
|
|
18
18
|
},
|
|
19
19
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
20
20
|
async run({ text, deep }, { client }, extra) {
|
|
21
|
+
const { options, progress } = verifyOptions(deep, extra);
|
|
21
22
|
try {
|
|
22
|
-
const report = await client.verifyText(text,
|
|
23
|
-
|
|
23
|
+
const report = await client.verifyText(text, options);
|
|
24
|
+
await progress.flush();
|
|
25
|
+
return ok(formatReport(report, rememberReport(report)), { summary: publicSummary(report.summary), coverage: report.coverage });
|
|
24
26
|
}
|
|
25
27
|
catch (err) {
|
|
28
|
+
await progress.flush();
|
|
26
29
|
return fail(err);
|
|
27
30
|
}
|
|
28
31
|
},
|
|
29
32
|
});
|
|
30
33
|
/** Deep checks stream rows; each finished row becomes a progress notification when the client asked for progress. */
|
|
31
34
|
export function verifyOptions(deep, extra) {
|
|
32
|
-
if (!deep)
|
|
33
|
-
return { signal: extra.signal };
|
|
34
35
|
const progress = progressReporter(extra);
|
|
36
|
+
if (!deep)
|
|
37
|
+
return { options: { signal: extra.signal }, progress };
|
|
35
38
|
if (extra._meta?.progressToken === undefined)
|
|
36
|
-
return { deep: true, signal: extra.signal };
|
|
39
|
+
return { options: { deep: true, signal: extra.signal }, progress };
|
|
37
40
|
let done = 0;
|
|
38
41
|
return {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
progress,
|
|
43
|
+
options: {
|
|
44
|
+
deep: true,
|
|
45
|
+
signal: extra.signal,
|
|
46
|
+
onRow: (row, report) => {
|
|
47
|
+
done += 1;
|
|
48
|
+
progress.report(done, report.summary.deep_pending, `${row.citation}: ${row.support?.headline ?? row.headline}`);
|
|
49
|
+
},
|
|
44
50
|
},
|
|
45
51
|
};
|
|
46
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check_citations.js","sourceRoot":"","sources":["../../src/tools/check_citations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"check_citations.js","sourceRoot":"","sources":["../../src/tools/check_citations.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,48 +1,56 @@
|
|
|
1
1
|
import { readFile, stat } from "node:fs/promises";
|
|
2
|
-
import { basename, extname } from "node:path";
|
|
2
|
+
import { basename, extname, isAbsolute } from "node:path";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { MAX_UPLOAD_BYTES } from "../client.js";
|
|
5
5
|
import { formatReport } from "../format.js";
|
|
6
6
|
import { rememberReport } from "../reports.js";
|
|
7
7
|
import { verifyOptions } from "./check_citations.js";
|
|
8
|
-
import { DEEP_NOTE, LIMITS_NOTE, defineTool, fail, ok } from "./tool.js";
|
|
8
|
+
import { DEEP_NOTE, KEY_NOTE, LIMITS_NOTE, defineTool, fail, ok, publicSummary } from "./tool.js";
|
|
9
9
|
const ALLOWED = new Set([".pdf", ".docx", ".txt", ".md"]);
|
|
10
10
|
export const checkDocument = defineTool({
|
|
11
11
|
name: "check_document",
|
|
12
12
|
title: "Check legal citations in a file",
|
|
13
|
-
description: "Check every case citation in a document on disk (PDF, DOCX or
|
|
13
|
+
description: "Check every case citation in a document on disk (PDF, DOCX, TXT or Markdown, up to 10 MB) against proofread.law's register of about 10 million US court opinions. " +
|
|
14
14
|
"The file is read here and uploaded to proofread.law, which extracts the text in memory, checks it and discards it. " +
|
|
15
15
|
"Returns the same compact result as check_citations: coverage statement, counts per tier, one line per red (check this) or orange (cannot verify) row, " +
|
|
16
16
|
"the number of citations found, and a report id for render_report. " +
|
|
17
17
|
"Scanned PDFs without a text layer, encrypted PDFs and legacy .doc files cannot be read; .docx needs a paid plan. " +
|
|
18
|
-
LIMITS_NOTE + " " + DEEP_NOTE,
|
|
18
|
+
LIMITS_NOTE + " " + DEEP_NOTE + " " + KEY_NOTE,
|
|
19
19
|
inputSchema: {
|
|
20
|
-
path: z.string().min(1).describe("Absolute path to a .pdf, .docx or .
|
|
20
|
+
path: z.string().min(1).describe("Absolute path to a .pdf, .docx, .txt or .md file on this machine."),
|
|
21
21
|
deep: z.boolean().optional().describe("Also check whether each cited opinion supports the sentence it is cited for. Slower, opt-in, 3 per month on the free tier."),
|
|
22
22
|
},
|
|
23
23
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
24
24
|
async run({ path, deep }, { client }, extra) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return fail(new Error(`${path}: only .pdf, .docx, .txt and .md files can be checked`));
|
|
28
|
-
}
|
|
25
|
+
if (!isAbsolute(path))
|
|
26
|
+
return fail(`${path}: give an absolute path (this server does not know the client's working directory).`);
|
|
29
27
|
let bytes;
|
|
30
28
|
try {
|
|
31
29
|
const info = await stat(path);
|
|
30
|
+
if (info.isDirectory())
|
|
31
|
+
return fail(`${path} is a directory; give the path of one .pdf, .docx, .txt or .md file.`);
|
|
32
32
|
if (!info.isFile())
|
|
33
|
-
return fail(
|
|
33
|
+
return fail(`${path} is not a regular file.`);
|
|
34
|
+
const ext = extname(path).toLowerCase();
|
|
35
|
+
if (!ALLOWED.has(ext))
|
|
36
|
+
return fail(`${path}: only .pdf, .docx, .txt and .md files can be checked.`);
|
|
34
37
|
if (info.size > MAX_UPLOAD_BYTES)
|
|
35
|
-
return fail(
|
|
38
|
+
return fail(`${path} is ${info.size} bytes; the cap is 10 MB.`);
|
|
36
39
|
bytes = await readFile(path);
|
|
37
40
|
}
|
|
38
41
|
catch (err) {
|
|
39
|
-
|
|
42
|
+
const code = err.code;
|
|
43
|
+
const why = code === "ENOENT" ? "no such file" : code === "EACCES" ? "permission denied" : err instanceof Error ? err.message : String(err);
|
|
44
|
+
return fail(`could not read ${path}: ${why}.`);
|
|
40
45
|
}
|
|
46
|
+
const { options, progress } = verifyOptions(deep, extra);
|
|
41
47
|
try {
|
|
42
|
-
const report = await client.verifyFile(bytes, basename(path),
|
|
43
|
-
|
|
48
|
+
const report = await client.verifyFile(bytes, basename(path), options);
|
|
49
|
+
await progress.flush();
|
|
50
|
+
return ok(formatReport(report, rememberReport(report)), { summary: publicSummary(report.summary), coverage: report.coverage, input: report.input ?? null });
|
|
44
51
|
}
|
|
45
52
|
catch (err) {
|
|
53
|
+
await progress.flush();
|
|
46
54
|
return fail(err);
|
|
47
55
|
}
|
|
48
56
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check_document.js","sourceRoot":"","sources":["../../src/tools/check_document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"check_document.js","sourceRoot":"","sources":["../../src/tools/check_document.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { billingLink } from "./billing_link.js";
|
|
1
2
|
import { checkCitations } from "./check_citations.js";
|
|
2
3
|
import { checkDocument } from "./check_document.js";
|
|
3
4
|
import { coverage } from "./coverage.js";
|
|
4
5
|
import { renderReport } from "./render_report.js";
|
|
5
6
|
import { resolveCitation } from "./resolve_citation.js";
|
|
6
7
|
import { resolveCitations } from "./resolve_citations.js";
|
|
8
|
+
import { signUp } from "./sign_up.js";
|
|
7
9
|
// One file per tool. The remaining register routes (/v1/extract, /v1/case/{id}, /v1/coverage per reporter) slot in the same way:
|
|
8
10
|
// a method on the client, a file here.
|
|
9
|
-
export const tools = [checkCitations, checkDocument, resolveCitation, resolveCitations, coverage, renderReport];
|
|
11
|
+
export const tools = [checkCitations, checkDocument, resolveCitation, resolveCitations, coverage, renderReport, signUp, billingLink];
|
|
10
12
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtC,iIAAiI;AACjI,uCAAuC;AACvC,MAAM,CAAC,MAAM,KAAK,GAAc,CAAC,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC"}
|
|
@@ -5,8 +5,8 @@ export const renderReport = defineTool({
|
|
|
5
5
|
name: "render_report",
|
|
6
6
|
title: "Render a check as a markdown report",
|
|
7
7
|
description: "Turn a finished check into a markdown diligence report: header, coverage and storage notices, a summary table sorted check-this, cannot-verify, support, found, " +
|
|
8
|
-
"and a detail block per flagged row with the register evidence. Use it when the user wants a report to keep or attach to the file. " +
|
|
9
|
-
"Pass the report_id returned by check_citations or check_document (ids live in this server's memory until it exits), or the full report JSON from proofread.law's /verify endpoint.",
|
|
8
|
+
"and a detail block per flagged row with the register evidence. Use it when the user wants a report to keep or attach to the file, or when the compact result was cut short. " +
|
|
9
|
+
"Pass the report_id returned by check_citations or check_document (ids live in this server's memory until it exits), or the full report JSON from proofread.law's /verify endpoint. Free, not counted.",
|
|
10
10
|
inputSchema: {
|
|
11
11
|
report_id: z.string().regex(/^r_[0-9a-f]{8}$/).optional().describe("The 'Report id' from a previous check_citations or check_document result."),
|
|
12
12
|
report: z.record(z.string(), z.unknown()).optional().describe("A full report JSON as returned by POST /verify, if you have one instead of an id."),
|
|
@@ -17,13 +17,13 @@ export const renderReport = defineTool({
|
|
|
17
17
|
if (report_id) {
|
|
18
18
|
source = recallReport(report_id);
|
|
19
19
|
if (!source)
|
|
20
|
-
return fail(
|
|
20
|
+
return fail(`no report ${report_id} in memory (this server keeps the last 50 checks until it exits). Run the check again and use the new id.`);
|
|
21
21
|
}
|
|
22
22
|
else if (report && isReport(report)) {
|
|
23
23
|
source = report;
|
|
24
24
|
}
|
|
25
25
|
else {
|
|
26
|
-
return fail(
|
|
26
|
+
return fail("give either report_id (from a previous check) or report (the full JSON from /verify with summary, rows, coverage and storage).");
|
|
27
27
|
}
|
|
28
28
|
try {
|
|
29
29
|
return ok(await client.renderMarkdown(source, extra.signal));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render_report.js","sourceRoot":"","sources":["../../src/tools/render_report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;IACrC,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,qCAAqC;IAC5C,WAAW,EACT,kKAAkK;QAClK,
|
|
1
|
+
{"version":3,"file":"render_report.js","sourceRoot":"","sources":["../../src/tools/render_report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;IACrC,IAAI,EAAE,eAAe;IACrB,KAAK,EAAE,qCAAqC;IAC5C,WAAW,EACT,kKAAkK;QAClK,8KAA8K;QAC9K,uMAAuM;IACzM,WAAW,EAAE;QACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2EAA2E,CAAC;QAC/I,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mFAAmF,CAAC;KACnJ;IACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;IACtG,KAAK,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK;QAChD,IAAI,MAA0B,CAAC;QAC/B,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;YACjC,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC,aAAa,SAAS,2GAA2G,CAAC,CAAC;QAC9J,CAAC;aAAM,IAAI,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,MAAM,GAAG,MAAM,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,gIAAgI,CAAC,CAAC;QAChJ,CAAC;QACD,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,MAAM,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;CACF,CAAC,CAAC;AAEH,SAAS,QAAQ,CAAC,KAA8B;IAC9C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC;AACxI,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { formatResolve } from "../resolve_format.js";
|
|
3
|
-
import { LIMITS_NOTE, defineTool, fail, ok } from "./tool.js";
|
|
3
|
+
import { KEY_NOTE, LIMITS_NOTE, defineTool, fail, ok } from "./tool.js";
|
|
4
4
|
export const resolveCitation = defineTool({
|
|
5
5
|
name: "resolve_citation",
|
|
6
6
|
title: "Look up one citation in the register",
|
|
@@ -10,7 +10,7 @@ export const resolveCitation = defineTool({
|
|
|
10
10
|
"Statuses: found; ambiguous (several entries, candidates listed); not in the register (a register fact with a coverage qualifier, never proof that the case does not exist); " +
|
|
11
11
|
"cannot verify (a Westlaw/Lexis identifier, or a volume the register cannot see yet); known citation (other opinions cite it, the opinion itself is not held); no citation recognised. " +
|
|
12
12
|
"Use it when one citation is in doubt; use check_citations for prose, and resolve_citations for a list. " +
|
|
13
|
-
LIMITS_NOTE + " Counts against the resolve quota (1,000 a month free), not the check quota.",
|
|
13
|
+
LIMITS_NOTE + " Counts against the resolve quota (1,000 a month free), not the check quota. " + KEY_NOTE,
|
|
14
14
|
inputSchema: {
|
|
15
15
|
citation: z.string().min(3).max(500).describe("One citation string. A case name and year around it are fine; only the reporter citation is resolved."),
|
|
16
16
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve_citation.js","sourceRoot":"","sources":["../../src/tools/resolve_citation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve_citation.js","sourceRoot":"","sources":["../../src/tools/resolve_citation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAExE,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC;IACxC,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE,sCAAsC;IAC7C,WAAW,EACT,2JAA2J;QAC3J,+IAA+I;QAC/I,8KAA8K;QAC9K,8KAA8K;QAC9K,wLAAwL;QACxL,yGAAyG;QACzG,WAAW,GAAG,+EAA+E,GAAG,QAAQ;IAC1G,WAAW,EAAE;QACX,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,uGAAuG,CAAC;KACvJ;IACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;IACtG,KAAK,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK;QACvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC9D,OAAO,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE;gBAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,IAAI,EAAE,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI;gBACtC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI;gBACzK,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,IAAI;aACtD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { MAX_BATCH_CITES } from "../client.js";
|
|
3
3
|
import { formatResolveBatch } from "../resolve_format.js";
|
|
4
|
-
import { LIMITS_NOTE, defineTool, fail, ok } from "./tool.js";
|
|
4
|
+
import { KEY_NOTE, LIMITS_NOTE, defineTool, fail, ok } from "./tool.js";
|
|
5
5
|
export const resolveCitations = defineTool({
|
|
6
6
|
name: "resolve_citations",
|
|
7
7
|
title: "Look up a list of citations in the register",
|
|
@@ -9,7 +9,7 @@ export const resolveCitations = defineTool({
|
|
|
9
9
|
"found (the case, court, date, link), ambiguous, not in the register (a register fact with a coverage qualifier, never proof that the case does not exist), " +
|
|
10
10
|
"cannot verify (Westlaw/Lexis identifier, or a volume the register cannot see yet), known citation, or no citation recognised. " +
|
|
11
11
|
"Use it for a table of authorities or any list of citations you already have; use check_citations for prose (it also checks names and quotations). " +
|
|
12
|
-
LIMITS_NOTE + " Each citation counts against the resolve quota (1,000 a month free), not the check quota.",
|
|
12
|
+
LIMITS_NOTE + " Each citation counts against the resolve quota (1,000 a month free), not the check quota. " + KEY_NOTE,
|
|
13
13
|
inputSchema: {
|
|
14
14
|
cites: z.array(z.string().min(1).max(500)).min(1).max(MAX_BATCH_CITES).describe("Citation strings, one per entry, up to 500."),
|
|
15
15
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve_citations.js","sourceRoot":"","sources":["../../src/tools/resolve_citations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve_citations.js","sourceRoot":"","sources":["../../src/tools/resolve_citations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAExE,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;IACzC,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,6CAA6C;IACpD,WAAW,EACT,iIAAiI;QACjI,6JAA6J;QAC7J,gIAAgI;QAChI,oJAAoJ;QACpJ,WAAW,GAAG,6FAA6F,GAAG,QAAQ;IACxH,WAAW,EAAE;QACX,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;KAC/H;IACD,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;IACtG,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK;QACpC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YAC7D,OAAO,EAAE,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE;gBACnC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC5K,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;aAC7C,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { defineTool, fail, ok } from "./tool.js";
|
|
3
|
+
export const signUp = defineTool({
|
|
4
|
+
name: "sign_up",
|
|
5
|
+
title: "Create a proofread.law account and API key",
|
|
6
|
+
description: "Open a proofread.law account for its owner and get an API key, in one call (POST /agent/signup). Use it when the user wants their own quota " +
|
|
7
|
+
"instead of the anonymous per-IP free tier, or before billing_link. The email must be the account OWNER's real inbox (placeholder domains are rejected); " +
|
|
8
|
+
"the owner receives one confirmation email and nothing else. The key is shown once: this server adopts it for the rest of this session, and the user " +
|
|
9
|
+
"should put it in PROOFREAD_API_KEY in their MCP configuration so it survives a restart. Never send the key anywhere but proofread.law. " +
|
|
10
|
+
"Calling again with the same address while the account is unconfirmed and unpaid rotates the key; a confirmed or paying account answers 409 " +
|
|
11
|
+
"(the owner manages keys at https://proofread.law/account). Free tier per account: 20 checks, 3 deep checks, 1,000 resolves a month; 5 sign-ups an hour per client.",
|
|
12
|
+
inputSchema: {
|
|
13
|
+
email: z.string().email().max(254).describe("The account owner's real email address. Ask the user for it; do not invent one."),
|
|
14
|
+
agent_name: z.string().min(1).max(64).regex(/^[A-Za-z0-9 ._-]+$/).describe("A name for this agent or client (1 to 64 characters: letters, digits, spaces, dots, hyphens, underscores), e.g. 'Claude Desktop'."),
|
|
15
|
+
},
|
|
16
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
17
|
+
async run({ email, agent_name }, { client }, extra) {
|
|
18
|
+
try {
|
|
19
|
+
const { created, result } = await client.signUp(email, agent_name, extra.signal);
|
|
20
|
+
client.setApiKey(result.api_key);
|
|
21
|
+
const l = result.limits ?? {};
|
|
22
|
+
const limits = [
|
|
23
|
+
l.checks_per_month !== undefined ? `${l.checks_per_month} checks` : undefined,
|
|
24
|
+
l.deep_checks_per_month !== undefined ? `${l.deep_checks_per_month} deep checks` : undefined,
|
|
25
|
+
l.resolves_per_month !== undefined ? `${l.resolves_per_month} resolves` : undefined,
|
|
26
|
+
].filter(Boolean).join(", ");
|
|
27
|
+
const text = [
|
|
28
|
+
created
|
|
29
|
+
? `Account created for ${email} (plan: ${result.plan ?? "free"}). The owner has been sent one confirmation email.`
|
|
30
|
+
: `The account for ${email} already existed and was unconfirmed; its previous key was revoked and a new one issued.`,
|
|
31
|
+
`API key (shown once): ${result.api_key}`,
|
|
32
|
+
"This server now uses the key for the rest of this session. Tell the user to store it as PROOFREAD_API_KEY in the MCP server configuration so it survives a restart, and never send it anywhere except proofread.law.",
|
|
33
|
+
limits ? `Free tier per month: ${limits}. When it runs out, billing_link gives the owner a checkout page.` : "When the free tier runs out, billing_link gives the owner a checkout page.",
|
|
34
|
+
].join("\n");
|
|
35
|
+
return ok(text, { created, email, plan: result.plan ?? "free", key_prefix: result.key_prefix ?? null });
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
return fail(err);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=sign_up.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign_up.js","sourceRoot":"","sources":["../../src/tools/sign_up.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAC;IAC/B,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,4CAA4C;IACnD,WAAW,EACT,8IAA8I;QAC9I,0JAA0J;QAC1J,sJAAsJ;QACtJ,yIAAyI;QACzI,6IAA6I;QAC7I,oKAAoK;IACtK,WAAW,EAAE;QACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,iFAAiF,CAAC;QAC9H,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,QAAQ,CAAC,mIAAmI,CAAC;KAChN;IACD,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE;IACxG,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK;QAChD,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YACjF,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACjC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG;gBACb,CAAC,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,gBAAgB,SAAS,CAAC,CAAC,CAAC,SAAS;gBAC7E,CAAC,CAAC,qBAAqB,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,qBAAqB,cAAc,CAAC,CAAC,CAAC,SAAS;gBAC5F,CAAC,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,kBAAkB,WAAW,CAAC,CAAC,CAAC,SAAS;aACpF,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7B,MAAM,IAAI,GAAG;gBACX,OAAO;oBACL,CAAC,CAAC,uBAAuB,KAAK,WAAW,MAAM,CAAC,IAAI,IAAI,MAAM,oDAAoD;oBAClH,CAAC,CAAC,mBAAmB,KAAK,0FAA0F;gBACtH,yBAAyB,MAAM,CAAC,OAAO,EAAE;gBACzC,sNAAsN;gBACtN,MAAM,CAAC,CAAC,CAAC,wBAAwB,MAAM,mEAAmE,CAAC,CAAC,CAAC,4EAA4E;aAC1L,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC,CAAC;QAC1G,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
|
package/dist/tools/tool.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/proto
|
|
|
2
2
|
import type { CallToolResult, ServerNotification, ServerRequest, ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
|
|
3
3
|
import type { z } from "zod";
|
|
4
4
|
import type { Client } from "../client.js";
|
|
5
|
+
import type { Summary } from "../types.js";
|
|
5
6
|
export type ToolExtra = RequestHandlerExtra<ServerRequest, ServerNotification>;
|
|
6
7
|
export interface ToolContext {
|
|
7
8
|
client: Client;
|
|
@@ -17,9 +18,17 @@ export interface ToolDef<Shape extends z.ZodRawShape = z.ZodRawShape> {
|
|
|
17
18
|
}
|
|
18
19
|
export declare function defineTool<Shape extends z.ZodRawShape>(def: ToolDef<Shape>): ToolDef<Shape>;
|
|
19
20
|
export declare function ok(text: string, structuredContent?: Record<string, unknown>): CallToolResult;
|
|
20
|
-
/** Errors go back as a tool result the model can read and act on, not as a protocol error. */
|
|
21
|
+
/** Errors go back as a tool result the model can read and act on, not as a protocol error. A string is the sentence itself. */
|
|
21
22
|
export declare function fail(err: unknown): CallToolResult;
|
|
23
|
+
export interface Progress {
|
|
24
|
+
report(done: number, total: number | undefined, message: string): void;
|
|
25
|
+
/** Wait for the notifications to be written before the result goes out, so none arrives after it. */
|
|
26
|
+
flush(): Promise<void>;
|
|
27
|
+
}
|
|
22
28
|
/** Sends MCP progress notifications when the client asked for them (deep checks take a while). */
|
|
23
|
-
export declare function progressReporter(extra: ToolExtra):
|
|
29
|
+
export declare function progressReporter(extra: ToolExtra): Progress;
|
|
30
|
+
/** The summary as structured content: the API's counts without its internal cost counter. */
|
|
31
|
+
export declare function publicSummary(summary: Summary): Record<string, unknown>;
|
|
24
32
|
export declare const LIMITS_NOTE: string;
|
|
25
33
|
export declare const DEEP_NOTE: string;
|
|
34
|
+
export declare const KEY_NOTE = "Without an API key the free tier applies per IP address; a key from sign_up (free tier) identifies the account, and a paid-plan key lifts the limits.";
|
package/dist/tools/tool.js
CHANGED
|
@@ -5,24 +5,37 @@ export function defineTool(def) {
|
|
|
5
5
|
export function ok(text, structuredContent) {
|
|
6
6
|
return structuredContent ? { content: [{ type: "text", text }], structuredContent } : { content: [{ type: "text", text }] };
|
|
7
7
|
}
|
|
8
|
-
/** Errors go back as a tool result the model can read and act on, not as a protocol error. */
|
|
8
|
+
/** Errors go back as a tool result the model can read and act on, not as a protocol error. A string is the sentence itself. */
|
|
9
9
|
export function fail(err) {
|
|
10
10
|
return { content: [{ type: "text", text: explain(err) }], isError: true };
|
|
11
11
|
}
|
|
12
12
|
/** Sends MCP progress notifications when the client asked for them (deep checks take a while). */
|
|
13
13
|
export function progressReporter(extra) {
|
|
14
14
|
const token = extra._meta?.progressToken;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
.
|
|
15
|
+
const pending = [];
|
|
16
|
+
return {
|
|
17
|
+
report(done, total, message) {
|
|
18
|
+
if (token === undefined)
|
|
19
|
+
return;
|
|
20
|
+
const capped = total !== undefined ? Math.max(total, done) : undefined;
|
|
21
|
+
pending.push(extra
|
|
22
|
+
.sendNotification({ method: "notifications/progress", params: { progressToken: token, progress: done, ...(capped !== undefined ? { total: capped } : {}), message } })
|
|
23
|
+
.catch(() => { }));
|
|
24
|
+
},
|
|
25
|
+
async flush() {
|
|
26
|
+
await Promise.allSettled(pending);
|
|
27
|
+
},
|
|
21
28
|
};
|
|
22
29
|
}
|
|
30
|
+
/** The summary as structured content: the API's counts without its internal cost counter. */
|
|
31
|
+
export function publicSummary(summary) {
|
|
32
|
+
const { jev_spent_today_usd: _cost, ...rest } = summary;
|
|
33
|
+
return rest;
|
|
34
|
+
}
|
|
23
35
|
export const LIMITS_NOTE = "Cannot: resolve Westlaw (WL) or Lexis identifiers, check statutes, regulations or secondary sources, or say whether a case is still good law. " +
|
|
24
36
|
"A red row means 'check this', never 'this case does not exist'; an orange row means the register has nothing to check against, which is not evidence either way.";
|
|
25
37
|
export const DEEP_NOTE = "deep=true also asks, for each found citation, whether the opinion supports the sentence it is cited for (white rows). " +
|
|
26
38
|
"It is slower (1 to 2 s per citation), opt-in because the clause before each citation is sent to a model judge, limited to 3 per month on the free tier, " +
|
|
27
39
|
"and its answers are a review queue, not a verdict.";
|
|
40
|
+
export const KEY_NOTE = "Without an API key the free tier applies per IP address; a key from sign_up (free tier) identifies the account, and a paid-plan key lifts the limits.";
|
|
28
41
|
//# sourceMappingURL=tool.js.map
|
package/dist/tools/tool.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/tools/tool.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/tools/tool.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAmBvC,MAAM,UAAU,UAAU,CAA8B,GAAmB;IACzE,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,EAAE,CAAC,IAAY,EAAE,iBAA2C;IAC1E,OAAO,iBAAiB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC9H,CAAC;AAED,+HAA+H;AAC/H,MAAM,UAAU,IAAI,CAAC,GAAY;IAC/B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC5E,CAAC;AAQD,kGAAkG;AAClG,MAAM,UAAU,gBAAgB,CAAC,KAAgB;IAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,aAAa,CAAC;IACzC,MAAM,OAAO,GAAoB,EAAE,CAAC;IACpC,OAAO;QACL,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO;YACzB,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO;YAChC,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACvE,OAAO,CAAC,IAAI,CAAC,KAAK;iBACf,gBAAgB,CAAC,EAAE,MAAM,EAAE,wBAAwB,EAAE,MAAM,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;iBACrK,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC;QACtB,CAAC;QACD,KAAK,CAAC,KAAK;YACT,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,MAAM,EAAE,mBAAmB,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACxD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GACtB,gJAAgJ;IAChJ,kKAAkK,CAAC;AAErK,MAAM,CAAC,MAAM,SAAS,GACpB,wHAAwH;IACxH,0JAA0J;IAC1J,oDAAoD,CAAC;AAEvD,MAAM,CAAC,MAAM,QAAQ,GACnB,uJAAuJ,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -138,3 +138,22 @@ export interface ResolveBatch {
|
|
|
138
138
|
plan?: string;
|
|
139
139
|
elapsed_s?: number;
|
|
140
140
|
}
|
|
141
|
+
export interface SignupResult {
|
|
142
|
+
api_key: string;
|
|
143
|
+
key_prefix?: string;
|
|
144
|
+
plan?: string;
|
|
145
|
+
email?: string;
|
|
146
|
+
agent_name?: string;
|
|
147
|
+
limits?: {
|
|
148
|
+
checks_per_month?: number;
|
|
149
|
+
deep_checks_per_month?: number;
|
|
150
|
+
resolves_per_month?: number;
|
|
151
|
+
requests_per_hour?: number;
|
|
152
|
+
};
|
|
153
|
+
[key: string]: unknown;
|
|
154
|
+
}
|
|
155
|
+
export interface CheckoutLink {
|
|
156
|
+
checkout_url: string;
|
|
157
|
+
plan?: string;
|
|
158
|
+
note?: string;
|
|
159
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "proofread-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"mcpName": "io.github.Data-Alchemy-Labs/proofread-mcp",
|
|
4
5
|
"description": "MCP server for proofread.law: check legal citations from Claude, Cursor or the OpenAI Agents SDK",
|
|
5
6
|
"license": "MIT",
|
|
6
7
|
"author": "Data Alchemy Labs",
|