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 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 eight tools: issue a free key, run the four validators (deflated Sharpe,
5
- CSCV overfitting, paper-evidence conformance, breadth ceiling), fetch a stored receipt, read
6
- service status, and read a company's reported financial history from SEC filings. Every tool
7
- returns the full API envelope as its result text, success or error, so the agent cannot see a
8
- number without the sentences beside it that say what the number does not establish.
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.1",
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 },