@crscreditapi/finstack-mcp-server 0.1.0-2bad4fe
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/.env.example +13 -0
- package/dist/api/client.d.ts +23 -0
- package/dist/api/client.js +81 -0
- package/dist/api/customer.api.d.ts +46 -0
- package/dist/api/customer.api.js +12 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.js +5 -0
- package/dist/handlers/customer.handler.d.ts +6 -0
- package/dist/handlers/customer.handler.js +9 -0
- package/dist/handlers/index.d.ts +5 -0
- package/dist/handlers/index.js +7 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +88 -0
- package/dist/resources.d.ts +16 -0
- package/dist/resources.js +7 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.js +45 -0
- package/dist/tools/customer.tools.d.ts +5 -0
- package/dist/tools/customer.tools.js +21 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.js +2 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +4 -0
- package/dist/types/tool.types.d.ts +27 -0
- package/dist/types/tool.types.js +4 -0
- package/package.json +41 -0
package/.env.example
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Transport mode: "stdio" (default, for Claude Code) or "http" (for n8n / EC2)
|
|
2
|
+
MCP_TRANSPORT=stdio
|
|
3
|
+
|
|
4
|
+
# HTTP transport port (only used when MCP_TRANSPORT=http)
|
|
5
|
+
MCP_PORT=3002
|
|
6
|
+
|
|
7
|
+
# === mware-portal API ===
|
|
8
|
+
FINSTACK_PROD_BASE_URL=https://portal.example.com
|
|
9
|
+
# FINSTACK_DEV_BASE_URL=https://portal-dev.example.com
|
|
10
|
+
# FINSTACK_TIMEOUT_MS=30000
|
|
11
|
+
|
|
12
|
+
# Shared secret for the mware-portal chatbase endpoints (X-Chatbase-Secret header)
|
|
13
|
+
FINSTACK_CHATBASE_SECRET=
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client skeleton for the B2B API.
|
|
3
|
+
*
|
|
4
|
+
* No auth wired up yet — add Authorization header / login flow once the
|
|
5
|
+
* upstream API is decided. This is a thin fetch wrapper with timeouts.
|
|
6
|
+
*/
|
|
7
|
+
export type Environment = 'dev' | 'prod';
|
|
8
|
+
interface ApiClientConfig {
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
timeoutMs: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class ApiClient {
|
|
13
|
+
private config;
|
|
14
|
+
constructor(config: ApiClientConfig);
|
|
15
|
+
private fetchWithTimeout;
|
|
16
|
+
private request;
|
|
17
|
+
get<T>(path: string, headers?: Record<string, string>): Promise<T>;
|
|
18
|
+
post<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
19
|
+
put<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
|
|
20
|
+
del<T>(path: string, headers?: Record<string, string>): Promise<T>;
|
|
21
|
+
}
|
|
22
|
+
export declare function getClient(env?: Environment): ApiClient;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client skeleton for the B2B API.
|
|
3
|
+
*
|
|
4
|
+
* No auth wired up yet — add Authorization header / login flow once the
|
|
5
|
+
* upstream API is decided. This is a thin fetch wrapper with timeouts.
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
8
|
+
export class ApiClient {
|
|
9
|
+
config;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
}
|
|
13
|
+
fetchWithTimeout(url, options) {
|
|
14
|
+
const controller = new AbortController();
|
|
15
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeoutMs);
|
|
16
|
+
return fetch(url, { ...options, signal: controller.signal }).finally(() => clearTimeout(timeoutId));
|
|
17
|
+
}
|
|
18
|
+
async request(method, path, body, headers) {
|
|
19
|
+
const options = {
|
|
20
|
+
method,
|
|
21
|
+
headers: {
|
|
22
|
+
...(body !== undefined && { 'Content-Type': 'application/json' }),
|
|
23
|
+
...headers,
|
|
24
|
+
},
|
|
25
|
+
...(body !== undefined && { body: JSON.stringify(body) }),
|
|
26
|
+
};
|
|
27
|
+
const response = await this.fetchWithTimeout(`${this.config.baseUrl}${path}`, options);
|
|
28
|
+
if (!response.ok) {
|
|
29
|
+
const error = await response.text();
|
|
30
|
+
throw new Error(`${method} ${path} failed: ${response.status} - ${error}`);
|
|
31
|
+
}
|
|
32
|
+
return response.json();
|
|
33
|
+
}
|
|
34
|
+
async get(path, headers) {
|
|
35
|
+
return this.request('GET', path, undefined, headers);
|
|
36
|
+
}
|
|
37
|
+
async post(path, body, headers) {
|
|
38
|
+
return this.request('POST', path, body, headers);
|
|
39
|
+
}
|
|
40
|
+
async put(path, body, headers) {
|
|
41
|
+
return this.request('PUT', path, body, headers);
|
|
42
|
+
}
|
|
43
|
+
async del(path, headers) {
|
|
44
|
+
return this.request('DELETE', path, undefined, headers);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function loadConfigs() {
|
|
48
|
+
const timeoutMs = process.env.FINSTACK_TIMEOUT_MS
|
|
49
|
+
? parseInt(process.env.FINSTACK_TIMEOUT_MS, 10)
|
|
50
|
+
: DEFAULT_TIMEOUT_MS;
|
|
51
|
+
const prodBaseUrl = process.env.FINSTACK_PROD_BASE_URL;
|
|
52
|
+
if (!prodBaseUrl) {
|
|
53
|
+
throw new Error('FINSTACK_PROD_BASE_URL must be set');
|
|
54
|
+
}
|
|
55
|
+
const prodConfig = {
|
|
56
|
+
baseUrl: prodBaseUrl,
|
|
57
|
+
timeoutMs,
|
|
58
|
+
};
|
|
59
|
+
const devBaseUrl = process.env.FINSTACK_DEV_BASE_URL;
|
|
60
|
+
const devConfig = devBaseUrl
|
|
61
|
+
? { baseUrl: devBaseUrl, timeoutMs }
|
|
62
|
+
: prodConfig;
|
|
63
|
+
return { prod: prodConfig, dev: devConfig };
|
|
64
|
+
}
|
|
65
|
+
let _prodClient = null;
|
|
66
|
+
let _devClient = null;
|
|
67
|
+
function ensureInit() {
|
|
68
|
+
if (_prodClient)
|
|
69
|
+
return;
|
|
70
|
+
const configs = loadConfigs();
|
|
71
|
+
_prodClient = new ApiClient(configs.prod);
|
|
72
|
+
_devClient = new ApiClient(configs.dev);
|
|
73
|
+
}
|
|
74
|
+
export function getClient(env = 'prod') {
|
|
75
|
+
ensureInit();
|
|
76
|
+
const client = env === 'dev' ? _devClient : _prodClient;
|
|
77
|
+
if (!client) {
|
|
78
|
+
throw new Error(`The ${env} environment is not configured.`);
|
|
79
|
+
}
|
|
80
|
+
return client;
|
|
81
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer-related calls against the mware-portal API.
|
|
3
|
+
*/
|
|
4
|
+
import type { ApiClient } from './client.js';
|
|
5
|
+
export interface CustomerSummary {
|
|
6
|
+
summary: string;
|
|
7
|
+
account: {
|
|
8
|
+
onboarding_path: string | null;
|
|
9
|
+
onboarding_completion_percent: number;
|
|
10
|
+
completed_tasks: number;
|
|
11
|
+
total_tasks: number;
|
|
12
|
+
};
|
|
13
|
+
onboarding_steps: Array<{
|
|
14
|
+
name: string;
|
|
15
|
+
type: string;
|
|
16
|
+
status: string;
|
|
17
|
+
}>;
|
|
18
|
+
products: Array<{
|
|
19
|
+
vendor: string | null;
|
|
20
|
+
product: string;
|
|
21
|
+
add_ons: string | null;
|
|
22
|
+
platform: string | null;
|
|
23
|
+
status: 'activated' | 'not_activated';
|
|
24
|
+
}>;
|
|
25
|
+
api_credentials: Record<'sandbox' | 'production', {
|
|
26
|
+
configured: boolean;
|
|
27
|
+
enabled_count: number;
|
|
28
|
+
platforms: string[];
|
|
29
|
+
}>;
|
|
30
|
+
inspection: {
|
|
31
|
+
status: 'not_ordered';
|
|
32
|
+
} | {
|
|
33
|
+
status: string;
|
|
34
|
+
inspection_type: string;
|
|
35
|
+
};
|
|
36
|
+
billing: {
|
|
37
|
+
payment_method_on_file: boolean;
|
|
38
|
+
recent_invoices: Array<{
|
|
39
|
+
name: string;
|
|
40
|
+
date: string;
|
|
41
|
+
amount: string | number;
|
|
42
|
+
status: string;
|
|
43
|
+
}>;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export declare function getCustomerSummary(client: ApiClient, customerCode: string): Promise<CustomerSummary>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export async function getCustomerSummary(client, customerCode) {
|
|
2
|
+
const secret = process.env.FINSTACK_CHATBASE_SECRET;
|
|
3
|
+
if (!secret) {
|
|
4
|
+
throw new Error('FINSTACK_CHATBASE_SECRET must be set');
|
|
5
|
+
}
|
|
6
|
+
const params = new URLSearchParams({ customer_code: customerCode });
|
|
7
|
+
const response = await client.get(`/api/v1/chatbase/customer_context?${params}`, { 'X-Chatbase-Secret': secret });
|
|
8
|
+
if (response.status !== 'success' || !response.data) {
|
|
9
|
+
throw new Error(response.message || 'Failed to fetch customer summary');
|
|
10
|
+
}
|
|
11
|
+
return response.data;
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer tool handlers
|
|
3
|
+
*/
|
|
4
|
+
import { getClient } from '../api/client.js';
|
|
5
|
+
import { getCustomerSummary } from '../api/customer.api.js';
|
|
6
|
+
export async function handleGetCustomerSummary(args) {
|
|
7
|
+
const client = getClient(args.environment ?? 'prod');
|
|
8
|
+
return getCustomerSummary(client, args.customer_code);
|
|
9
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Finstack MCP Server Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Supports two transport modes via MCP_TRANSPORT env var:
|
|
6
|
+
* - "stdio" (default): For CLI tools like Claude Code
|
|
7
|
+
* - "http": Streamable HTTP for n8n and other HTTP-based MCP clients
|
|
8
|
+
*/
|
|
9
|
+
import 'dotenv/config';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Finstack MCP Server Entry Point
|
|
4
|
+
*
|
|
5
|
+
* Supports two transport modes via MCP_TRANSPORT env var:
|
|
6
|
+
* - "stdio" (default): For CLI tools like Claude Code
|
|
7
|
+
* - "http": Streamable HTTP for n8n and other HTTP-based MCP clients
|
|
8
|
+
*/
|
|
9
|
+
import 'dotenv/config';
|
|
10
|
+
import { tools } from './tools/index.js';
|
|
11
|
+
import { handlers } from './handlers/index.js';
|
|
12
|
+
import { createServer } from './server.js';
|
|
13
|
+
async function main() {
|
|
14
|
+
const mode = process.env.MCP_TRANSPORT || 'stdio';
|
|
15
|
+
if (mode === 'http') {
|
|
16
|
+
await startHttpServer();
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
await startStdioServer();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function startStdioServer() {
|
|
23
|
+
const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js');
|
|
24
|
+
const server = createServer(tools, handlers);
|
|
25
|
+
const transport = new StdioServerTransport();
|
|
26
|
+
await server.connect(transport);
|
|
27
|
+
console.error('finstack-mcp-server running (stdio)');
|
|
28
|
+
}
|
|
29
|
+
async function startHttpServer() {
|
|
30
|
+
const { StreamableHTTPServerTransport } = await import('@modelcontextprotocol/sdk/server/streamableHttp.js');
|
|
31
|
+
const express = (await import('express')).default;
|
|
32
|
+
const port = parseInt(process.env.MCP_PORT || '3002', 10);
|
|
33
|
+
const app = express();
|
|
34
|
+
app.use(express.json());
|
|
35
|
+
app.use((req, _res, next) => {
|
|
36
|
+
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url} Host:${req.headers.host} Accept:${req.headers.accept}`);
|
|
37
|
+
if (req.body && Object.keys(req.body).length > 0) {
|
|
38
|
+
console.log(` Body: ${JSON.stringify(req.body).substring(0, 200)}`);
|
|
39
|
+
}
|
|
40
|
+
next();
|
|
41
|
+
});
|
|
42
|
+
const handlePost = async (req, res) => {
|
|
43
|
+
const server = createServer(tools, handlers);
|
|
44
|
+
const transport = new StreamableHTTPServerTransport({
|
|
45
|
+
sessionIdGenerator: undefined,
|
|
46
|
+
});
|
|
47
|
+
await server.connect(transport);
|
|
48
|
+
try {
|
|
49
|
+
await transport.handleRequest(req, res, req.body);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
console.error('Error handling MCP request:', error);
|
|
53
|
+
if (!res.headersSent) {
|
|
54
|
+
res.status(500).json({
|
|
55
|
+
jsonrpc: '2.0',
|
|
56
|
+
error: { code: -32603, message: 'Internal server error' },
|
|
57
|
+
id: null,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
res.on('close', () => {
|
|
62
|
+
transport.close();
|
|
63
|
+
server.close();
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
const handleMethodNotAllowed = (_req, res) => {
|
|
67
|
+
res.writeHead(405).end(JSON.stringify({
|
|
68
|
+
jsonrpc: '2.0',
|
|
69
|
+
error: { code: -32000, message: 'Method not allowed. Use POST.' },
|
|
70
|
+
id: null,
|
|
71
|
+
}));
|
|
72
|
+
};
|
|
73
|
+
app.get('/health', (_req, res) => {
|
|
74
|
+
res.json({ status: 'ok', uptime: process.uptime() });
|
|
75
|
+
});
|
|
76
|
+
app.post('/', handlePost);
|
|
77
|
+
app.post('/mcp', handlePost);
|
|
78
|
+
app.get('/', handleMethodNotAllowed);
|
|
79
|
+
app.get('/mcp', handleMethodNotAllowed);
|
|
80
|
+
app.listen(port, '0.0.0.0', () => {
|
|
81
|
+
console.error(`finstack-mcp-server running (http) on port ${port}`);
|
|
82
|
+
console.error(` Health: http://localhost:${port}/health`);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
main().catch((err) => {
|
|
86
|
+
console.error('Fatal error:', err);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Resources configuration
|
|
3
|
+
*/
|
|
4
|
+
export interface Resource {
|
|
5
|
+
uri: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
mimeType: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ResourceContent {
|
|
11
|
+
uri: string;
|
|
12
|
+
mimeType: string;
|
|
13
|
+
text: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const resources: Resource[];
|
|
16
|
+
export declare function getResourceContent(_uri: string): ResourceContent | null;
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server configuration
|
|
3
|
+
*/
|
|
4
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
5
|
+
import type { ToolDefinition, Handler } from './types/tool.types.js';
|
|
6
|
+
export declare function createServer(tools: ToolDefinition[], handlers: Record<string, Handler>): Server;
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server configuration
|
|
3
|
+
*/
|
|
4
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
5
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ErrorCode, McpError, } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
import { resources, getResourceContent } from './resources.js';
|
|
7
|
+
export function createServer(tools, handlers) {
|
|
8
|
+
const server = new Server({ name: 'finstack-mcp-server', version: '0.1.0' }, { capabilities: { tools: {}, resources: {} } });
|
|
9
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
10
|
+
tools,
|
|
11
|
+
}));
|
|
12
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
13
|
+
const { name, arguments: args } = request.params;
|
|
14
|
+
const handler = handlers[name];
|
|
15
|
+
if (!handler) {
|
|
16
|
+
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const result = await handler((args || {}));
|
|
20
|
+
return {
|
|
21
|
+
content: [
|
|
22
|
+
{ type: 'text', text: JSON.stringify(result, null, 2) },
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
28
|
+
return {
|
|
29
|
+
content: [{ type: 'text', text: `Error: ${message}` }],
|
|
30
|
+
isError: true,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
35
|
+
resources,
|
|
36
|
+
}));
|
|
37
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
38
|
+
const content = getResourceContent(request.params.uri);
|
|
39
|
+
if (!content) {
|
|
40
|
+
throw new McpError(ErrorCode.InvalidRequest, `Unknown resource: ${request.params.uri}`);
|
|
41
|
+
}
|
|
42
|
+
return { contents: [content] };
|
|
43
|
+
});
|
|
44
|
+
return server;
|
|
45
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const customerTools = [
|
|
2
|
+
{
|
|
3
|
+
name: 'get_customer_summary',
|
|
4
|
+
description: 'Fetch a non-PII summary of a B2B customer: onboarding progress, products, API credentials, inspection status, and recent billing. Backed by the mware-portal chatbase customer_context endpoint.',
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: 'object',
|
|
7
|
+
properties: {
|
|
8
|
+
customer_code: {
|
|
9
|
+
type: 'string',
|
|
10
|
+
description: 'Customer code (CID) — e.g. "ABC123"',
|
|
11
|
+
},
|
|
12
|
+
environment: {
|
|
13
|
+
type: 'string',
|
|
14
|
+
description: 'Target environment: "prod" (default) or "dev"',
|
|
15
|
+
enum: ['dev', 'prod'],
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
required: ['customer_code'],
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool registry.
|
|
3
|
+
*
|
|
4
|
+
* Add per-domain tool definitions here, e.g.:
|
|
5
|
+
* import { fooTools } from './foo.tools.js';
|
|
6
|
+
* export const tools: ToolDefinition[] = [...fooTools];
|
|
7
|
+
*/
|
|
8
|
+
import type { ToolDefinition } from '../types/tool.types.js';
|
|
9
|
+
export declare const tools: ToolDefinition[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tool type definitions
|
|
3
|
+
*/
|
|
4
|
+
export interface JsonSchemaProperty {
|
|
5
|
+
type?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
enum?: string[];
|
|
8
|
+
items?: JsonSchemaProperty;
|
|
9
|
+
properties?: Record<string, JsonSchemaProperty>;
|
|
10
|
+
required?: string[];
|
|
11
|
+
minItems?: number;
|
|
12
|
+
maxItems?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ToolInputSchema {
|
|
15
|
+
type: 'object';
|
|
16
|
+
properties: Record<string, JsonSchemaProperty>;
|
|
17
|
+
required?: string[];
|
|
18
|
+
anyOf?: Array<{
|
|
19
|
+
required: string[];
|
|
20
|
+
}>;
|
|
21
|
+
}
|
|
22
|
+
export interface ToolDefinition {
|
|
23
|
+
name: string;
|
|
24
|
+
description: string;
|
|
25
|
+
inputSchema: ToolInputSchema;
|
|
26
|
+
}
|
|
27
|
+
export type Handler = (args: Record<string, unknown>) => Promise<unknown>;
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@crscreditapi/finstack-mcp-server",
|
|
3
|
+
"version": "0.1.0-2bad4fe",
|
|
4
|
+
"description": "MCP server for Finstack",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"finstack-mcp-server": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/**/*",
|
|
13
|
+
".env.example"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=18.0.0"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/StitchCredit/finstack-mcp-server.git"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"registry": "https://registry.npmjs.org",
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc",
|
|
28
|
+
"start": "node dist/index.js",
|
|
29
|
+
"prepublishOnly": "npm run build"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
33
|
+
"dotenv": "^16.3.0",
|
|
34
|
+
"express": "^5.2.1"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/express": "^5.0.6",
|
|
38
|
+
"@types/node": "^20.11.0",
|
|
39
|
+
"typescript": "^5.3.0"
|
|
40
|
+
}
|
|
41
|
+
}
|