canli-validation-mcp 0.3.1 → 0.4.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/README.md +7 -5
- package/package.json +1 -1
- package/src/schemas.mjs +17 -0
- package/src/server.mjs +12 -0
package/README.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# canli-validation-mcp
|
|
2
2
|
|
|
3
3
|
An MCP (Model Context Protocol) server over canlicapital.com's free, keyed validation API. It
|
|
4
|
-
gives a coding agent
|
|
5
|
-
CSCV overfitting, paper-evidence conformance, breadth ceiling
|
|
6
|
-
service status, and read a company's reported financial history
|
|
7
|
-
returns the full API envelope as its result text, success or error,
|
|
8
|
-
number without the sentences beside it that say what the number does
|
|
4
|
+
gives a coding agent nine tools: issue a free key, run the five validators (deflated Sharpe,
|
|
5
|
+
CSCV overfitting, paper-evidence conformance, breadth ceiling, minimum track record length),
|
|
6
|
+
fetch a stored receipt, read service status, and read a company's reported financial history
|
|
7
|
+
from SEC filings. Every tool returns the full API envelope as its result text, success or error,
|
|
8
|
+
so the agent cannot see a number without the sentences beside it that say what the number does
|
|
9
|
+
not establish.
|
|
9
10
|
|
|
10
11
|
This package is published to npm as [`canli-validation-mcp`](https://www.npmjs.com/package/canli-validation-mcp).
|
|
11
12
|
Also listed on the official MCP Registry (`io.github.arhancanli/canli-validation-mcp`) and
|
|
@@ -33,6 +34,7 @@ repository for the full design.
|
|
|
33
34
|
| `validate_overfitting` | `POST /api/v1/validate/overfitting` | yes |
|
|
34
35
|
| `validate_paper_evidence` | `POST /api/v1/validate/paper-evidence` | yes |
|
|
35
36
|
| `validate_breadth` | `POST /api/v1/validate/breadth` | yes |
|
|
37
|
+
| `validate_track_record` | `POST /api/v1/validate/track-record` | yes |
|
|
36
38
|
| `get_receipt` | `GET /api/v1/receipts/{id}` | no |
|
|
37
39
|
| `service_status` | `GET /api/v1/validate/status` | no |
|
|
38
40
|
| `company_financial_history` | `GET /company-data/{cik}.json` | no |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canli-validation-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "MCP server for canlicapital.com's free validation API: deflated Sharpe, CSCV overfitting, paper-evidence conformance, and breadth ceiling, each returned as the full API envelope so the boundary language cannot be dropped.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
package/src/schemas.mjs
CHANGED
|
@@ -92,6 +92,22 @@ export const breadthInput = z
|
|
|
92
92
|
})
|
|
93
93
|
.strict();
|
|
94
94
|
|
|
95
|
+
// ---------------------------------------------------------------------------------------------
|
|
96
|
+
// validate_track_record
|
|
97
|
+
// ---------------------------------------------------------------------------------------------
|
|
98
|
+
|
|
99
|
+
export const trackRecordInput = z
|
|
100
|
+
.object({
|
|
101
|
+
observed_sharpe_annualized: z.number().min(-10).max(10),
|
|
102
|
+
periods_per_year: z.number().min(1).max(10000),
|
|
103
|
+
skew: z.number().min(-20).max(20),
|
|
104
|
+
non_excess_kurtosis: z.number().min(1).max(100),
|
|
105
|
+
benchmark_sharpe_annualized: z.number().min(-10).max(10).optional(),
|
|
106
|
+
confidence: z.number().gt(0).lt(1).optional(),
|
|
107
|
+
observations: z.number().int().min(2).max(1000000).optional(),
|
|
108
|
+
})
|
|
109
|
+
.strict();
|
|
110
|
+
|
|
95
111
|
// ---------------------------------------------------------------------------------------------
|
|
96
112
|
// get_key / get_receipt
|
|
97
113
|
// ---------------------------------------------------------------------------------------------
|
|
@@ -151,6 +167,7 @@ export const TOOL_DESCRIPTIONS = Object.freeze({
|
|
|
151
167
|
validate_deflated_sharpe: `Probabilistic and deflated Sharpe from the seven contract inputs, or from a return series plus the trials and dispersion behind it, never both. ${LIMITS_SENTENCES.notAdmission}`,
|
|
152
168
|
validate_overfitting: `Probability of backtest overfitting by CSCV over the returns of every variant tried. ${LIMITS_SENTENCES.notAdmission}`,
|
|
153
169
|
validate_paper_evidence: `Conformance of a performance record against the canli.paper-evidence.v0 standard. ${LIMITS_SENTENCES.scope}`,
|
|
170
|
+
validate_track_record: `Minimum track record length for an observed Sharpe to clear a benchmark Sharpe (default 0) at a confidence level (default 0.95), and, when observations is sent, the probabilistic Sharpe of that record against the benchmark. ${LIMITS_SENTENCES.notAdmission}`,
|
|
154
171
|
validate_breadth: `Book Sharpe ceiling from per-sleeve quality and average pairwise correlation, and the sleeves a target needs. ${LIMITS_SENTENCES.scope}`,
|
|
155
172
|
get_receipt: `Fetch a stored verdict by its content-hash id (GET /api/v1/receipts/{id}), immutable and cacheable. ${LIMITS_SENTENCES.unsigned}`,
|
|
156
173
|
service_status: `Service, store and quota constants for the validation API (GET /api/v1/validate/status); no key required. ${LIMITS_SENTENCES.scope}`,
|
package/src/server.mjs
CHANGED
|
@@ -12,6 +12,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
12
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
13
13
|
import {
|
|
14
14
|
breadthInput,
|
|
15
|
+
trackRecordInput,
|
|
15
16
|
companyHistoryInput,
|
|
16
17
|
deflatedSharpeInput,
|
|
17
18
|
deflatedSharpeToolShape,
|
|
@@ -168,6 +169,12 @@ export async function toolValidateBreadth(session, args) {
|
|
|
168
169
|
return asText(response.envelope, response.failed);
|
|
169
170
|
}
|
|
170
171
|
|
|
172
|
+
export async function toolValidateTrackRecord(session, args) {
|
|
173
|
+
const body = parseOrThrow(trackRecordInput, args, "validate_track_record");
|
|
174
|
+
const response = await callApi(session, { path: "/api/v1/validate/track-record", method: "POST", body });
|
|
175
|
+
return asText(response.envelope, response.failed);
|
|
176
|
+
}
|
|
177
|
+
|
|
171
178
|
export async function toolGetReceipt(session, args) {
|
|
172
179
|
const { id } = parseOrThrow(getReceiptInput, args, "get_receipt");
|
|
173
180
|
const response = await callApi(session, { path: `/api/v1/receipts/${id}` });
|
|
@@ -282,6 +289,11 @@ export function registerTools(server, session) {
|
|
|
282
289
|
{ title: "Validate breadth ceiling", annotations: { title: "Validate breadth ceiling", ...WRITES_RECEIPT }, description: TOOL_DESCRIPTIONS.validate_breadth, inputSchema: breadthInput },
|
|
283
290
|
(args) => toolValidateBreadth(session, args),
|
|
284
291
|
);
|
|
292
|
+
server.registerTool(
|
|
293
|
+
"validate_track_record",
|
|
294
|
+
{ title: "Minimum track record length", annotations: { title: "Minimum track record length", ...WRITES_RECEIPT }, description: TOOL_DESCRIPTIONS.validate_track_record, inputSchema: trackRecordInput },
|
|
295
|
+
(args) => toolValidateTrackRecord(session, args),
|
|
296
|
+
);
|
|
285
297
|
server.registerTool(
|
|
286
298
|
"get_receipt",
|
|
287
299
|
{ title: "Get a receipt", annotations: { title: "Get a receipt", ...READ_ONLY }, description: TOOL_DESCRIPTIONS.get_receipt, inputSchema: getReceiptInput },
|