cas-parser-node-mcp 1.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 +201 -0
- package/README.md +208 -0
- package/compat.d.mts +56 -0
- package/compat.d.mts.map +1 -0
- package/compat.d.ts +56 -0
- package/compat.d.ts.map +1 -0
- package/compat.js +385 -0
- package/compat.js.map +1 -0
- package/compat.mjs +376 -0
- package/compat.mjs.map +1 -0
- package/dynamic-tools.d.mts +12 -0
- package/dynamic-tools.d.mts.map +1 -0
- package/dynamic-tools.d.ts +12 -0
- package/dynamic-tools.d.ts.map +1 -0
- package/dynamic-tools.js +135 -0
- package/dynamic-tools.js.map +1 -0
- package/dynamic-tools.mjs +132 -0
- package/dynamic-tools.mjs.map +1 -0
- package/filtering.d.mts +2 -0
- package/filtering.d.mts.map +1 -0
- package/filtering.d.ts +2 -0
- package/filtering.d.ts.map +1 -0
- package/filtering.js +20 -0
- package/filtering.js.map +1 -0
- package/filtering.mjs +13 -0
- package/filtering.mjs.map +1 -0
- package/headers.d.mts +4 -0
- package/headers.d.mts.map +1 -0
- package/headers.d.ts +4 -0
- package/headers.d.ts.map +1 -0
- package/headers.js +10 -0
- package/headers.js.map +1 -0
- package/headers.mjs +6 -0
- package/headers.mjs.map +1 -0
- package/http.d.mts +6 -0
- package/http.d.mts.map +1 -0
- package/http.d.ts +6 -0
- package/http.d.ts.map +1 -0
- package/http.js +93 -0
- package/http.js.map +1 -0
- package/http.mjs +85 -0
- package/http.mjs.map +1 -0
- package/index.d.mts +3 -0
- package/index.d.mts.map +1 -0
- package/index.d.ts +3 -0
- package/index.d.ts.map +1 -0
- package/index.js +91 -0
- package/index.js.map +1 -0
- package/index.mjs +89 -0
- package/index.mjs.map +1 -0
- package/options.d.mts +17 -0
- package/options.d.mts.map +1 -0
- package/options.d.ts +17 -0
- package/options.d.ts.map +1 -0
- package/options.js +314 -0
- package/options.js.map +1 -0
- package/options.mjs +308 -0
- package/options.mjs.map +1 -0
- package/package.json +163 -0
- package/server.d.mts +48 -0
- package/server.d.mts.map +1 -0
- package/server.d.ts +48 -0
- package/server.d.ts.map +1 -0
- package/server.js +129 -0
- package/server.js.map +1 -0
- package/server.mjs +115 -0
- package/server.mjs.map +1 -0
- package/src/compat.ts +481 -0
- package/src/dynamic-tools.ts +159 -0
- package/src/filtering.ts +14 -0
- package/src/headers.ts +11 -0
- package/src/http.ts +99 -0
- package/src/index.ts +108 -0
- package/src/options.ts +341 -0
- package/src/server.ts +165 -0
- package/src/stdio.ts +14 -0
- package/src/tools/cas-generator/generate-cas-cas-generator.ts +67 -0
- package/src/tools/cas-parser/cams-kfintech-cas-parser.ts +47 -0
- package/src/tools/cas-parser/cdsl-cas-parser.ts +47 -0
- package/src/tools/cas-parser/nsdl-cas-parser.ts +47 -0
- package/src/tools/cas-parser/smart-parse-cas-parser.ts +47 -0
- package/src/tools/index.ts +79 -0
- package/src/tools/types.ts +103 -0
- package/src/tools.ts +1 -0
- package/src/tsconfig.json +11 -0
- package/stdio.d.mts +4 -0
- package/stdio.d.mts.map +1 -0
- package/stdio.d.ts +4 -0
- package/stdio.d.ts.map +1 -0
- package/stdio.js +14 -0
- package/stdio.js.map +1 -0
- package/stdio.mjs +10 -0
- package/stdio.mjs.map +1 -0
- package/tools/cas-generator/generate-cas-cas-generator.d.mts +45 -0
- package/tools/cas-generator/generate-cas-cas-generator.d.mts.map +1 -0
- package/tools/cas-generator/generate-cas-cas-generator.d.ts +45 -0
- package/tools/cas-generator/generate-cas-cas-generator.d.ts.map +1 -0
- package/tools/cas-generator/generate-cas-cas-generator.js +62 -0
- package/tools/cas-generator/generate-cas-cas-generator.js.map +1 -0
- package/tools/cas-generator/generate-cas-cas-generator.mjs +58 -0
- package/tools/cas-generator/generate-cas-cas-generator.mjs.map +1 -0
- package/tools/cas-parser/cams-kfintech-cas-parser.d.mts +45 -0
- package/tools/cas-parser/cams-kfintech-cas-parser.d.mts.map +1 -0
- package/tools/cas-parser/cams-kfintech-cas-parser.d.ts +45 -0
- package/tools/cas-parser/cams-kfintech-cas-parser.d.ts.map +1 -0
- package/tools/cas-parser/cams-kfintech-cas-parser.js +43 -0
- package/tools/cas-parser/cams-kfintech-cas-parser.js.map +1 -0
- package/tools/cas-parser/cams-kfintech-cas-parser.mjs +39 -0
- package/tools/cas-parser/cams-kfintech-cas-parser.mjs.map +1 -0
- package/tools/cas-parser/cdsl-cas-parser.d.mts +45 -0
- package/tools/cas-parser/cdsl-cas-parser.d.mts.map +1 -0
- package/tools/cas-parser/cdsl-cas-parser.d.ts +45 -0
- package/tools/cas-parser/cdsl-cas-parser.d.ts.map +1 -0
- package/tools/cas-parser/cdsl-cas-parser.js +43 -0
- package/tools/cas-parser/cdsl-cas-parser.js.map +1 -0
- package/tools/cas-parser/cdsl-cas-parser.mjs +39 -0
- package/tools/cas-parser/cdsl-cas-parser.mjs.map +1 -0
- package/tools/cas-parser/nsdl-cas-parser.d.mts +45 -0
- package/tools/cas-parser/nsdl-cas-parser.d.mts.map +1 -0
- package/tools/cas-parser/nsdl-cas-parser.d.ts +45 -0
- package/tools/cas-parser/nsdl-cas-parser.d.ts.map +1 -0
- package/tools/cas-parser/nsdl-cas-parser.js +43 -0
- package/tools/cas-parser/nsdl-cas-parser.js.map +1 -0
- package/tools/cas-parser/nsdl-cas-parser.mjs +39 -0
- package/tools/cas-parser/nsdl-cas-parser.mjs.map +1 -0
- package/tools/cas-parser/smart-parse-cas-parser.d.mts +45 -0
- package/tools/cas-parser/smart-parse-cas-parser.d.mts.map +1 -0
- package/tools/cas-parser/smart-parse-cas-parser.d.ts +45 -0
- package/tools/cas-parser/smart-parse-cas-parser.d.ts.map +1 -0
- package/tools/cas-parser/smart-parse-cas-parser.js +43 -0
- package/tools/cas-parser/smart-parse-cas-parser.js.map +1 -0
- package/tools/cas-parser/smart-parse-cas-parser.mjs +39 -0
- package/tools/cas-parser/smart-parse-cas-parser.mjs.map +1 -0
- package/tools/index.d.mts +10 -0
- package/tools/index.d.mts.map +1 -0
- package/tools/index.d.ts +10 -0
- package/tools/index.d.ts.map +1 -0
- package/tools/index.js +63 -0
- package/tools/index.js.map +1 -0
- package/tools/index.mjs +56 -0
- package/tools/index.mjs.map +1 -0
- package/tools/types.d.mts +51 -0
- package/tools/types.d.mts.map +1 -0
- package/tools/types.d.ts +51 -0
- package/tools/types.d.ts.map +1 -0
- package/tools/types.js +46 -0
- package/tools/types.js.map +1 -0
- package/tools/types.mjs +42 -0
- package/tools/types.mjs.map +1 -0
- package/tools.d.mts +2 -0
- package/tools.d.mts.map +1 -0
- package/tools.d.ts +2 -0
- package/tools.d.ts.map +1 -0
- package/tools.js +18 -0
- package/tools.js.map +1 -0
- package/tools.mjs +2 -0
- package/tools.mjs.map +1 -0
package/src/server.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
|
+
import { Endpoint, endpoints, HandlerFunction, query } from './tools';
|
|
6
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
+
import { ClientOptions } from 'cas-parser-node';
|
|
8
|
+
import CasParser from 'cas-parser-node';
|
|
9
|
+
import {
|
|
10
|
+
applyCompatibilityTransformations,
|
|
11
|
+
ClientCapabilities,
|
|
12
|
+
defaultClientCapabilities,
|
|
13
|
+
knownClients,
|
|
14
|
+
parseEmbeddedJSON,
|
|
15
|
+
} from './compat';
|
|
16
|
+
import { dynamicTools } from './dynamic-tools';
|
|
17
|
+
import { McpOptions } from './options';
|
|
18
|
+
|
|
19
|
+
export { McpOptions } from './options';
|
|
20
|
+
export { ClientType } from './compat';
|
|
21
|
+
export { Filter } from './tools';
|
|
22
|
+
export { ClientOptions } from 'cas-parser-node';
|
|
23
|
+
export { endpoints } from './tools';
|
|
24
|
+
|
|
25
|
+
export const newMcpServer = () =>
|
|
26
|
+
new McpServer(
|
|
27
|
+
{
|
|
28
|
+
name: 'cas_parser_node_api',
|
|
29
|
+
version: '1.1.0',
|
|
30
|
+
},
|
|
31
|
+
{ capabilities: { tools: {}, logging: {} } },
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
// Create server instance
|
|
35
|
+
export const server = newMcpServer();
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Initializes the provided MCP Server with the given tools and handlers.
|
|
39
|
+
* If not provided, the default client, tools and handlers will be used.
|
|
40
|
+
*/
|
|
41
|
+
export function initMcpServer(params: {
|
|
42
|
+
server: Server | McpServer;
|
|
43
|
+
clientOptions: ClientOptions;
|
|
44
|
+
mcpOptions: McpOptions;
|
|
45
|
+
endpoints?: { tool: Tool; handler: HandlerFunction }[];
|
|
46
|
+
}) {
|
|
47
|
+
const transformedEndpoints = selectTools(endpoints, params.mcpOptions);
|
|
48
|
+
const client = new CasParser(params.clientOptions);
|
|
49
|
+
const capabilities = {
|
|
50
|
+
...defaultClientCapabilities,
|
|
51
|
+
...(params.mcpOptions.client ? knownClients[params.mcpOptions.client] : params.mcpOptions.capabilities),
|
|
52
|
+
};
|
|
53
|
+
init({ server: params.server, client, endpoints: transformedEndpoints, capabilities });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function init(params: {
|
|
57
|
+
server: Server | McpServer;
|
|
58
|
+
client?: CasParser;
|
|
59
|
+
endpoints?: { tool: Tool; handler: HandlerFunction }[];
|
|
60
|
+
capabilities?: Partial<ClientCapabilities>;
|
|
61
|
+
}) {
|
|
62
|
+
const server = params.server instanceof McpServer ? params.server.server : params.server;
|
|
63
|
+
const providedEndpoints = params.endpoints || endpoints;
|
|
64
|
+
|
|
65
|
+
const endpointMap = Object.fromEntries(providedEndpoints.map((endpoint) => [endpoint.tool.name, endpoint]));
|
|
66
|
+
|
|
67
|
+
const logAtLevel =
|
|
68
|
+
(level: 'debug' | 'info' | 'warning' | 'error') =>
|
|
69
|
+
(message: string, ...rest: unknown[]) => {
|
|
70
|
+
void server.sendLoggingMessage({
|
|
71
|
+
level,
|
|
72
|
+
data: { message, rest },
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
const logger = {
|
|
76
|
+
debug: logAtLevel('debug'),
|
|
77
|
+
info: logAtLevel('info'),
|
|
78
|
+
warn: logAtLevel('warning'),
|
|
79
|
+
error: logAtLevel('error'),
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const client =
|
|
83
|
+
params.client ||
|
|
84
|
+
new CasParser({
|
|
85
|
+
environment: (readEnv('CAS_PARSER_ENVIRONMENT') || undefined) as any,
|
|
86
|
+
defaultHeaders: { 'X-Stainless-MCP': 'true' },
|
|
87
|
+
logger: logger,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
91
|
+
return {
|
|
92
|
+
tools: providedEndpoints.map((endpoint) => endpoint.tool),
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
97
|
+
const { name, arguments: args } = request.params;
|
|
98
|
+
const endpoint = endpointMap[name];
|
|
99
|
+
if (!endpoint) {
|
|
100
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return executeHandler(endpoint.tool, endpoint.handler, client, args, params.capabilities);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Selects the tools to include in the MCP Server based on the provided options.
|
|
109
|
+
*/
|
|
110
|
+
export function selectTools(endpoints: Endpoint[], options: McpOptions): Endpoint[] {
|
|
111
|
+
const filteredEndpoints = query(options.filters, endpoints);
|
|
112
|
+
|
|
113
|
+
let includedTools = filteredEndpoints;
|
|
114
|
+
|
|
115
|
+
if (includedTools.length > 0) {
|
|
116
|
+
if (options.includeDynamicTools) {
|
|
117
|
+
includedTools = dynamicTools(includedTools);
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
if (options.includeAllTools) {
|
|
121
|
+
includedTools = endpoints;
|
|
122
|
+
} else if (options.includeDynamicTools) {
|
|
123
|
+
includedTools = dynamicTools(endpoints);
|
|
124
|
+
} else {
|
|
125
|
+
includedTools = endpoints;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const capabilities = { ...defaultClientCapabilities, ...options.capabilities };
|
|
130
|
+
return applyCompatibilityTransformations(includedTools, capabilities);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Runs the provided handler with the given client and arguments.
|
|
135
|
+
*/
|
|
136
|
+
export async function executeHandler(
|
|
137
|
+
tool: Tool,
|
|
138
|
+
handler: HandlerFunction,
|
|
139
|
+
client: CasParser,
|
|
140
|
+
args: Record<string, unknown> | undefined,
|
|
141
|
+
compatibilityOptions?: Partial<ClientCapabilities>,
|
|
142
|
+
) {
|
|
143
|
+
const options = { ...defaultClientCapabilities, ...compatibilityOptions };
|
|
144
|
+
if (!options.validJson && args) {
|
|
145
|
+
args = parseEmbeddedJSON(args, tool.inputSchema);
|
|
146
|
+
}
|
|
147
|
+
return await handler(client, args || {});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export const readEnv = (env: string): string | undefined => {
|
|
151
|
+
if (typeof (globalThis as any).process !== 'undefined') {
|
|
152
|
+
return (globalThis as any).process.env?.[env]?.trim();
|
|
153
|
+
} else if (typeof (globalThis as any).Deno !== 'undefined') {
|
|
154
|
+
return (globalThis as any).Deno.env?.get?.(env)?.trim();
|
|
155
|
+
}
|
|
156
|
+
return;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const readEnvOrError = (env: string): string => {
|
|
160
|
+
let envValue = readEnv(env);
|
|
161
|
+
if (envValue === undefined) {
|
|
162
|
+
throw new Error(`Environment variable ${env} is not set`);
|
|
163
|
+
}
|
|
164
|
+
return envValue;
|
|
165
|
+
};
|
package/src/stdio.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
2
|
+
import { init, newMcpServer } from './server';
|
|
3
|
+
import { Endpoint } from './tools';
|
|
4
|
+
import { McpOptions } from './options';
|
|
5
|
+
|
|
6
|
+
export const launchStdioServer = async (options: McpOptions, endpoints: Endpoint[]) => {
|
|
7
|
+
const server = newMcpServer();
|
|
8
|
+
|
|
9
|
+
init({ server, endpoints });
|
|
10
|
+
|
|
11
|
+
const transport = new StdioServerTransport();
|
|
12
|
+
await server.connect(transport);
|
|
13
|
+
console.error('MCP Server running on stdio');
|
|
14
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
import { maybeFilter } from 'cas-parser-node-mcp/filtering';
|
|
4
|
+
import { Metadata, asTextContentResult } from 'cas-parser-node-mcp/tools/types';
|
|
5
|
+
|
|
6
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
7
|
+
import CasParser from 'cas-parser-node';
|
|
8
|
+
|
|
9
|
+
export const metadata: Metadata = {
|
|
10
|
+
resource: 'CAS Generator',
|
|
11
|
+
operation: 'write',
|
|
12
|
+
tags: [],
|
|
13
|
+
httpMethod: 'post',
|
|
14
|
+
httpPath: '/v4/generate',
|
|
15
|
+
operationId: 'generateCAS',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const tool: Tool = {
|
|
19
|
+
name: 'generate_cas_cas_generator',
|
|
20
|
+
description:
|
|
21
|
+
"When using this tool, always use the `jq_filter` parameter to reduce the response size and improve performance.\n\nOnly omit if you're sure you don't need the data.\n\nThis endpoint generates CAS (Consolidated Account Statement) documents by submitting a mailback request to the specified CAS authority.\nCurrently only supports KFintech, with plans to support CAMS, CDSL, and NSDL in the future.\n\n\n# Response Schema\n```json\n{\n type: 'object',\n properties: {\n msg: {\n type: 'string'\n },\n status: {\n type: 'string'\n }\n }\n}\n```",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: {
|
|
25
|
+
email: {
|
|
26
|
+
type: 'string',
|
|
27
|
+
description: 'Email address to receive the CAS document',
|
|
28
|
+
},
|
|
29
|
+
from_date: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
description: 'Start date for the CAS period (format YYYY-MM-DD)',
|
|
32
|
+
},
|
|
33
|
+
password: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'Password to protect the generated CAS PDF',
|
|
36
|
+
},
|
|
37
|
+
to_date: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'End date for the CAS period (format YYYY-MM-DD)',
|
|
40
|
+
},
|
|
41
|
+
cas_authority: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
description: 'CAS authority to generate the document from (currently only kfintech is supported)',
|
|
44
|
+
enum: ['kfintech', 'cams', 'cdsl', 'nsdl'],
|
|
45
|
+
},
|
|
46
|
+
pan_no: {
|
|
47
|
+
type: 'string',
|
|
48
|
+
description: 'PAN number (optional for some CAS authorities)',
|
|
49
|
+
},
|
|
50
|
+
jq_filter: {
|
|
51
|
+
type: 'string',
|
|
52
|
+
title: 'jq Filter',
|
|
53
|
+
description:
|
|
54
|
+
'A jq filter to apply to the response to include certain fields. Consult the output schema in the tool description to see the fields that are available.\n\nFor example: to include only the `name` field in every object of a results array, you can provide ".results[].name".\n\nFor more information, see the [jq documentation](https://jqlang.org/manual/).',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
required: ['email', 'from_date', 'password', 'to_date'],
|
|
58
|
+
},
|
|
59
|
+
annotations: {},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const handler = async (client: CasParser, args: Record<string, unknown> | undefined) => {
|
|
63
|
+
const { jq_filter, ...body } = args as any;
|
|
64
|
+
return asTextContentResult(await maybeFilter(jq_filter, await client.casGenerator.generateCas(body)));
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default { metadata, tool, handler };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
import { Metadata, asTextContentResult } from 'cas-parser-node-mcp/tools/types';
|
|
4
|
+
|
|
5
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
import CasParser from 'cas-parser-node';
|
|
7
|
+
|
|
8
|
+
export const metadata: Metadata = {
|
|
9
|
+
resource: 'CAS Parser',
|
|
10
|
+
operation: 'write',
|
|
11
|
+
tags: [],
|
|
12
|
+
httpMethod: 'post',
|
|
13
|
+
httpPath: '/v4/cams_kfintech/parse',
|
|
14
|
+
operationId: 'camsKfintechParse',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const tool: Tool = {
|
|
18
|
+
name: 'cams_kfintech_cas_parser',
|
|
19
|
+
description:
|
|
20
|
+
'This endpoint specifically parses CAMS/KFintech CAS (Consolidated Account Statement) PDF files and returns data in a unified format.\nUse this endpoint when you know the PDF is from CAMS or KFintech.\n',
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
password: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
description: 'Password for the PDF file (if required)',
|
|
27
|
+
},
|
|
28
|
+
pdf_file: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
description: 'Base64 encoded CAS PDF file',
|
|
31
|
+
},
|
|
32
|
+
pdf_url: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'URL to the CAS PDF file',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
required: [],
|
|
38
|
+
},
|
|
39
|
+
annotations: {},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const handler = async (client: CasParser, args: Record<string, unknown> | undefined) => {
|
|
43
|
+
const body = args as any;
|
|
44
|
+
return asTextContentResult(await client.casParser.camsKfintech(body));
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default { metadata, tool, handler };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
import { Metadata, asTextContentResult } from 'cas-parser-node-mcp/tools/types';
|
|
4
|
+
|
|
5
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
import CasParser from 'cas-parser-node';
|
|
7
|
+
|
|
8
|
+
export const metadata: Metadata = {
|
|
9
|
+
resource: 'CAS Parser',
|
|
10
|
+
operation: 'write',
|
|
11
|
+
tags: [],
|
|
12
|
+
httpMethod: 'post',
|
|
13
|
+
httpPath: '/v4/cdsl/parse',
|
|
14
|
+
operationId: 'cdslParse',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const tool: Tool = {
|
|
18
|
+
name: 'cdsl_cas_parser',
|
|
19
|
+
description:
|
|
20
|
+
'This endpoint specifically parses CDSL CAS (Consolidated Account Statement) PDF files and returns data in a unified format.\nUse this endpoint when you know the PDF is from CDSL.\n',
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
password: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
description: 'Password for the PDF file (if required)',
|
|
27
|
+
},
|
|
28
|
+
pdf_file: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
description: 'Base64 encoded CAS PDF file',
|
|
31
|
+
},
|
|
32
|
+
pdf_url: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'URL to the CAS PDF file',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
required: [],
|
|
38
|
+
},
|
|
39
|
+
annotations: {},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const handler = async (client: CasParser, args: Record<string, unknown> | undefined) => {
|
|
43
|
+
const body = args as any;
|
|
44
|
+
return asTextContentResult(await client.casParser.cdsl(body));
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default { metadata, tool, handler };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
import { Metadata, asTextContentResult } from 'cas-parser-node-mcp/tools/types';
|
|
4
|
+
|
|
5
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
import CasParser from 'cas-parser-node';
|
|
7
|
+
|
|
8
|
+
export const metadata: Metadata = {
|
|
9
|
+
resource: 'CAS Parser',
|
|
10
|
+
operation: 'write',
|
|
11
|
+
tags: [],
|
|
12
|
+
httpMethod: 'post',
|
|
13
|
+
httpPath: '/v4/nsdl/parse',
|
|
14
|
+
operationId: 'nsdlParse',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const tool: Tool = {
|
|
18
|
+
name: 'nsdl_cas_parser',
|
|
19
|
+
description:
|
|
20
|
+
'This endpoint specifically parses NSDL CAS (Consolidated Account Statement) PDF files and returns data in a unified format.\nUse this endpoint when you know the PDF is from NSDL.\n',
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
password: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
description: 'Password for the PDF file (if required)',
|
|
27
|
+
},
|
|
28
|
+
pdf_file: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
description: 'Base64 encoded CAS PDF file',
|
|
31
|
+
},
|
|
32
|
+
pdf_url: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'URL to the CAS PDF file',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
required: [],
|
|
38
|
+
},
|
|
39
|
+
annotations: {},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const handler = async (client: CasParser, args: Record<string, unknown> | undefined) => {
|
|
43
|
+
const body = args as any;
|
|
44
|
+
return asTextContentResult(await client.casParser.nsdl(body));
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default { metadata, tool, handler };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
import { Metadata, asTextContentResult } from 'cas-parser-node-mcp/tools/types';
|
|
4
|
+
|
|
5
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
import CasParser from 'cas-parser-node';
|
|
7
|
+
|
|
8
|
+
export const metadata: Metadata = {
|
|
9
|
+
resource: 'CAS Parser',
|
|
10
|
+
operation: 'write',
|
|
11
|
+
tags: [],
|
|
12
|
+
httpMethod: 'post',
|
|
13
|
+
httpPath: '/v4/smart/parse',
|
|
14
|
+
operationId: 'smartParse',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const tool: Tool = {
|
|
18
|
+
name: 'smart_parse_cas_parser',
|
|
19
|
+
description:
|
|
20
|
+
'This endpoint parses CAS (Consolidated Account Statement) PDF files from NSDL, CDSL, or CAMS/KFintech and returns data in a unified format.\nIt auto-detects the CAS type and transforms the data into a consistent structure regardless of the source.\n',
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
password: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
description: 'Password for the PDF file (if required)',
|
|
27
|
+
},
|
|
28
|
+
pdf_file: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
description: 'Base64 encoded CAS PDF file',
|
|
31
|
+
},
|
|
32
|
+
pdf_url: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'URL to the CAS PDF file',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
required: [],
|
|
38
|
+
},
|
|
39
|
+
annotations: {},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const handler = async (client: CasParser, args: Record<string, unknown> | undefined) => {
|
|
43
|
+
const body = args as any;
|
|
44
|
+
return asTextContentResult(await client.casParser.smartParse(body));
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default { metadata, tool, handler };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
import { Metadata, Endpoint, HandlerFunction } from './types';
|
|
4
|
+
|
|
5
|
+
export { Metadata, Endpoint, HandlerFunction };
|
|
6
|
+
|
|
7
|
+
import cams_kfintech_cas_parser from './cas-parser/cams-kfintech-cas-parser';
|
|
8
|
+
import cdsl_cas_parser from './cas-parser/cdsl-cas-parser';
|
|
9
|
+
import nsdl_cas_parser from './cas-parser/nsdl-cas-parser';
|
|
10
|
+
import smart_parse_cas_parser from './cas-parser/smart-parse-cas-parser';
|
|
11
|
+
import generate_cas_cas_generator from './cas-generator/generate-cas-cas-generator';
|
|
12
|
+
|
|
13
|
+
export const endpoints: Endpoint[] = [];
|
|
14
|
+
|
|
15
|
+
function addEndpoint(endpoint: Endpoint) {
|
|
16
|
+
endpoints.push(endpoint);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
addEndpoint(cams_kfintech_cas_parser);
|
|
20
|
+
addEndpoint(cdsl_cas_parser);
|
|
21
|
+
addEndpoint(nsdl_cas_parser);
|
|
22
|
+
addEndpoint(smart_parse_cas_parser);
|
|
23
|
+
addEndpoint(generate_cas_cas_generator);
|
|
24
|
+
|
|
25
|
+
export type Filter = {
|
|
26
|
+
type: 'resource' | 'operation' | 'tag' | 'tool';
|
|
27
|
+
op: 'include' | 'exclude';
|
|
28
|
+
value: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export function query(filters: Filter[], endpoints: Endpoint[]): Endpoint[] {
|
|
32
|
+
const allExcludes = filters.length > 0 && filters.every((filter) => filter.op === 'exclude');
|
|
33
|
+
const unmatchedFilters = new Set(filters);
|
|
34
|
+
|
|
35
|
+
const filtered = endpoints.filter((endpoint: Endpoint) => {
|
|
36
|
+
let included = false || allExcludes;
|
|
37
|
+
|
|
38
|
+
for (const filter of filters) {
|
|
39
|
+
if (match(filter, endpoint)) {
|
|
40
|
+
unmatchedFilters.delete(filter);
|
|
41
|
+
included = filter.op === 'include';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return included;
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Check if any filters didn't match
|
|
49
|
+
const unmatched = Array.from(unmatchedFilters).filter((f) => f.type === 'tool' || f.type === 'resource');
|
|
50
|
+
if (unmatched.length > 0) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`The following filters did not match any endpoints: ${unmatched
|
|
53
|
+
.map((f) => `${f.type}=${f.value}`)
|
|
54
|
+
.join(', ')}`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return filtered;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function match({ type, value }: Filter, endpoint: Endpoint): boolean {
|
|
62
|
+
switch (type) {
|
|
63
|
+
case 'resource': {
|
|
64
|
+
const regexStr = '^' + normalizeResource(value).replace(/\*/g, '.*') + '$';
|
|
65
|
+
const regex = new RegExp(regexStr);
|
|
66
|
+
return regex.test(normalizeResource(endpoint.metadata.resource));
|
|
67
|
+
}
|
|
68
|
+
case 'operation':
|
|
69
|
+
return endpoint.metadata.operation === value;
|
|
70
|
+
case 'tag':
|
|
71
|
+
return endpoint.metadata.tags.includes(value);
|
|
72
|
+
case 'tool':
|
|
73
|
+
return endpoint.tool.name === value;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function normalizeResource(resource: string): string {
|
|
78
|
+
return resource.toLowerCase().replace(/[^a-z.*\-_]*/g, '');
|
|
79
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
import CasParser from 'cas-parser-node';
|
|
4
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
|
|
6
|
+
type TextContentBlock = {
|
|
7
|
+
type: 'text';
|
|
8
|
+
text: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
type ImageContentBlock = {
|
|
12
|
+
type: 'image';
|
|
13
|
+
data: string;
|
|
14
|
+
mimeType: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type AudioContentBlock = {
|
|
18
|
+
type: 'audio';
|
|
19
|
+
data: string;
|
|
20
|
+
mimeType: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type ResourceContentBlock = {
|
|
24
|
+
type: 'resource';
|
|
25
|
+
resource:
|
|
26
|
+
| {
|
|
27
|
+
uri: string;
|
|
28
|
+
mimeType: string;
|
|
29
|
+
text: string;
|
|
30
|
+
}
|
|
31
|
+
| {
|
|
32
|
+
uri: string;
|
|
33
|
+
mimeType: string;
|
|
34
|
+
blob: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type ContentBlock = TextContentBlock | ImageContentBlock | AudioContentBlock | ResourceContentBlock;
|
|
39
|
+
|
|
40
|
+
export type ToolCallResult = {
|
|
41
|
+
content: ContentBlock[];
|
|
42
|
+
isError?: boolean;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type HandlerFunction = (
|
|
46
|
+
client: CasParser,
|
|
47
|
+
args: Record<string, unknown> | undefined,
|
|
48
|
+
) => Promise<ToolCallResult>;
|
|
49
|
+
|
|
50
|
+
export function asTextContentResult(result: unknown): ToolCallResult {
|
|
51
|
+
return {
|
|
52
|
+
content: [
|
|
53
|
+
{
|
|
54
|
+
type: 'text',
|
|
55
|
+
text: JSON.stringify(result, null, 2),
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export async function asBinaryContentResult(response: Response): Promise<ToolCallResult> {
|
|
62
|
+
const blob = await response.blob();
|
|
63
|
+
const mimeType = blob.type;
|
|
64
|
+
const data = Buffer.from(await blob.arrayBuffer()).toString('base64');
|
|
65
|
+
if (mimeType.startsWith('image/')) {
|
|
66
|
+
return {
|
|
67
|
+
content: [{ type: 'image', mimeType, data }],
|
|
68
|
+
};
|
|
69
|
+
} else if (mimeType.startsWith('audio/')) {
|
|
70
|
+
return {
|
|
71
|
+
content: [{ type: 'audio', mimeType, data }],
|
|
72
|
+
};
|
|
73
|
+
} else {
|
|
74
|
+
return {
|
|
75
|
+
content: [
|
|
76
|
+
{
|
|
77
|
+
type: 'resource',
|
|
78
|
+
resource: {
|
|
79
|
+
// We must give a URI, even though this isn't actually an MCP resource.
|
|
80
|
+
uri: 'resource://tool-response',
|
|
81
|
+
mimeType,
|
|
82
|
+
blob: data,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export type Metadata = {
|
|
91
|
+
resource: string;
|
|
92
|
+
operation: 'read' | 'write';
|
|
93
|
+
tags: string[];
|
|
94
|
+
httpMethod?: string;
|
|
95
|
+
httpPath?: string;
|
|
96
|
+
operationId?: string;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export type Endpoint = {
|
|
100
|
+
metadata: Metadata;
|
|
101
|
+
tool: Tool;
|
|
102
|
+
handler: HandlerFunction;
|
|
103
|
+
};
|
package/src/tools.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './tools/index';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
// this config is included in the published src directory to prevent TS errors
|
|
3
|
+
// from appearing when users go to source, and VSCode opens the source .ts file
|
|
4
|
+
// via declaration maps
|
|
5
|
+
"include": ["index.ts"],
|
|
6
|
+
"compilerOptions": {
|
|
7
|
+
"target": "es2015",
|
|
8
|
+
"lib": ["DOM"],
|
|
9
|
+
"moduleResolution": "node"
|
|
10
|
+
}
|
|
11
|
+
}
|
package/stdio.d.mts
ADDED
package/stdio.d.mts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.d.mts","sourceRoot":"","sources":["src/stdio.ts"],"names":[],"mappings":"OAEO,EAAE,QAAQ,EAAE;OACZ,EAAE,UAAU,EAAE;AAErB,eAAO,MAAM,iBAAiB,GAAU,SAAS,UAAU,EAAE,WAAW,QAAQ,EAAE,kBAQjF,CAAC"}
|
package/stdio.d.ts
ADDED
package/stdio.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["src/stdio.ts"],"names":[],"mappings":"OAEO,EAAE,QAAQ,EAAE;OACZ,EAAE,UAAU,EAAE;AAErB,eAAO,MAAM,iBAAiB,GAAU,SAAS,UAAU,EAAE,WAAW,QAAQ,EAAE,kBAQjF,CAAC"}
|
package/stdio.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.launchStdioServer = void 0;
|
|
4
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
5
|
+
const server_1 = require("./server.js");
|
|
6
|
+
const launchStdioServer = async (options, endpoints) => {
|
|
7
|
+
const server = (0, server_1.newMcpServer)();
|
|
8
|
+
(0, server_1.init)({ server, endpoints });
|
|
9
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
10
|
+
await server.connect(transport);
|
|
11
|
+
console.error('MCP Server running on stdio');
|
|
12
|
+
};
|
|
13
|
+
exports.launchStdioServer = launchStdioServer;
|
|
14
|
+
//# sourceMappingURL=stdio.js.map
|
package/stdio.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["src/stdio.ts"],"names":[],"mappings":";;;AAAA,wEAAiF;AACjF,wCAA8C;AAIvC,MAAM,iBAAiB,GAAG,KAAK,EAAE,OAAmB,EAAE,SAAqB,EAAE,EAAE;IACpF,MAAM,MAAM,GAAG,IAAA,qBAAY,GAAE,CAAC;IAE9B,IAAA,aAAI,EAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IAE5B,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;AAC/C,CAAC,CAAC;AARW,QAAA,iBAAiB,qBAQ5B"}
|
package/stdio.mjs
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
2
|
+
import { init, newMcpServer } from "./server.mjs";
|
|
3
|
+
export const launchStdioServer = async (options, endpoints) => {
|
|
4
|
+
const server = newMcpServer();
|
|
5
|
+
init({ server, endpoints });
|
|
6
|
+
const transport = new StdioServerTransport();
|
|
7
|
+
await server.connect(transport);
|
|
8
|
+
console.error('MCP Server running on stdio');
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=stdio.mjs.map
|