@mcphero/vercel 1.1.6
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/.turbo/turbo-build.log +17 -0
- package/.turbo/turbo-check.log +14 -0
- package/.turbo/turbo-prepack.log +26 -0
- package/build/index.d.ts +15 -0
- package/build/index.js +93 -0
- package/build/index.js.map +1 -0
- package/eslint.config.mjs +99 -0
- package/package.json +38 -0
- package/src/adapter/vercel.ts +106 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +21 -0
- package/tsup.config.ts +13 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
> @mcphero/vercel@1.1.6 build /Users/atomic/projects/ai/mcphero/packages/vercel
|
|
3
|
+
> tsup
|
|
4
|
+
|
|
5
|
+
CLI Building entry: src/index.ts
|
|
6
|
+
CLI Using tsconfig: tsconfig.json
|
|
7
|
+
CLI tsup v8.5.1
|
|
8
|
+
CLI Using tsup config: /Users/atomic/projects/ai/mcphero/packages/vercel/tsup.config.ts
|
|
9
|
+
CLI Target: es2022
|
|
10
|
+
CLI Cleaning output folder
|
|
11
|
+
ESM Build start
|
|
12
|
+
ESM build/index.js 2.92 KB
|
|
13
|
+
ESM build/index.js.map 5.42 KB
|
|
14
|
+
ESM ⚡️ Build success in 5ms
|
|
15
|
+
DTS Build start
|
|
16
|
+
DTS ⚡️ Build success in 569ms
|
|
17
|
+
DTS build/index.d.ts 526.00 B
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
> @mcphero/vercel@1.1.6 check /Users/atomic/projects/ai/mcphero/packages/vercel
|
|
3
|
+
> pnpm lint && pnpm typecheck
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
> @mcphero/vercel@1.1.6 lint /Users/atomic/projects/ai/mcphero/packages/vercel
|
|
7
|
+
> eslint
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
> @mcphero/vercel@1.1.6 typecheck /Users/atomic/projects/ai/mcphero/packages/vercel
|
|
11
|
+
> tsc --noEmit
|
|
12
|
+
|
|
13
|
+
ELIFECYCLE Command failed.
|
|
14
|
+
ELIFECYCLE Command failed.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @mcphero/vercel@1.1.6 prepack /Users/atomic/projects/ai/mcphero/packages/vercel
|
|
4
|
+
> pnpm clean && pnpm build
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
> @mcphero/vercel@1.1.6 clean /Users/atomic/projects/ai/mcphero/packages/vercel
|
|
8
|
+
> rimraf build
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
> @mcphero/vercel@1.1.6 build /Users/atomic/projects/ai/mcphero/packages/vercel
|
|
12
|
+
> tsup
|
|
13
|
+
|
|
14
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
15
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
16
|
+
[34mCLI[39m tsup v8.5.1
|
|
17
|
+
[34mCLI[39m Using tsup config: /Users/atomic/projects/ai/mcphero/packages/vercel/tsup.config.ts
|
|
18
|
+
[34mCLI[39m Target: es2022
|
|
19
|
+
[34mCLI[39m Cleaning output folder
|
|
20
|
+
[34mESM[39m Build start
|
|
21
|
+
[32mESM[39m [1mbuild/index.js [22m[32m2.92 KB[39m
|
|
22
|
+
[32mESM[39m [1mbuild/index.js.map [22m[32m5.42 KB[39m
|
|
23
|
+
[32mESM[39m ⚡️ Build success in 9ms
|
|
24
|
+
DTS Build start
|
|
25
|
+
DTS ⚡️ Build success in 773ms
|
|
26
|
+
DTS build/index.d.ts 526.00 B
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AdapterGenerator } from '@mcphero/core';
|
|
2
|
+
|
|
3
|
+
interface VercelAdapterOptions {
|
|
4
|
+
enableJsonResponse?: boolean;
|
|
5
|
+
}
|
|
6
|
+
interface VercelAdapter {
|
|
7
|
+
adapter: AdapterGenerator;
|
|
8
|
+
handler: (request: Request) => Promise<Response>;
|
|
9
|
+
GET: (request: Request) => Promise<Response>;
|
|
10
|
+
POST: (request: Request) => Promise<Response>;
|
|
11
|
+
DELETE: (request: Request) => Promise<Response>;
|
|
12
|
+
}
|
|
13
|
+
declare function vercel(options?: VercelAdapterOptions): VercelAdapter;
|
|
14
|
+
|
|
15
|
+
export { type VercelAdapter, type VercelAdapterOptions, vercel };
|
package/build/index.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// src/adapter/vercel.ts
|
|
2
|
+
import { toolResponse } from "@mcphero/core";
|
|
3
|
+
import { createLogger } from "@mcphero/logger";
|
|
4
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
+
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
6
|
+
import { capitalCase, pascalCase } from "change-case";
|
|
7
|
+
function vercel(options = {}) {
|
|
8
|
+
let _actions = [];
|
|
9
|
+
let _options = null;
|
|
10
|
+
let _context = null;
|
|
11
|
+
let _readyResolve;
|
|
12
|
+
const _ready = new Promise((resolve) => {
|
|
13
|
+
_readyResolve = resolve;
|
|
14
|
+
});
|
|
15
|
+
const handleRequest = async (request) => {
|
|
16
|
+
await _ready;
|
|
17
|
+
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
18
|
+
sessionIdGenerator: void 0,
|
|
19
|
+
enableJsonResponse: options.enableJsonResponse
|
|
20
|
+
});
|
|
21
|
+
const server = new McpServer({
|
|
22
|
+
name: _options.name,
|
|
23
|
+
description: _options.description,
|
|
24
|
+
version: _options.version
|
|
25
|
+
}, {
|
|
26
|
+
capabilities: { tools: {}, logging: {} }
|
|
27
|
+
});
|
|
28
|
+
for (const action of _actions) {
|
|
29
|
+
server.registerTool(pascalCase(action.name), {
|
|
30
|
+
title: capitalCase(action.name),
|
|
31
|
+
description: action.description,
|
|
32
|
+
inputSchema: action.input
|
|
33
|
+
}, async (input, extra) => {
|
|
34
|
+
const logger = createLogger({
|
|
35
|
+
stream: process.stderr,
|
|
36
|
+
onLog: (level, data) => {
|
|
37
|
+
extra.sendNotification({ method: "notifications/message", params: { level, data } });
|
|
38
|
+
},
|
|
39
|
+
onProgress: ({ progress, total, message }) => {
|
|
40
|
+
if (!extra._meta?.progressToken) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
extra.sendNotification({
|
|
44
|
+
method: "notifications/progress",
|
|
45
|
+
params: {
|
|
46
|
+
progress,
|
|
47
|
+
total,
|
|
48
|
+
message,
|
|
49
|
+
progressToken: extra._meta.progressToken
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
return action.run(input, _context.fork({ logger, extra })).then((result) => {
|
|
55
|
+
return toolResponse(result);
|
|
56
|
+
}).catch((error) => {
|
|
57
|
+
if (error instanceof Error) {
|
|
58
|
+
return toolResponse({ success: false, name: error.name, message: error.message, stack: error.stack });
|
|
59
|
+
} else {
|
|
60
|
+
return toolResponse({ success: false, name: "Unknown Error", message: "An unknown error occured", error });
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
await server.connect(transport);
|
|
66
|
+
return transport.handleRequest(request);
|
|
67
|
+
};
|
|
68
|
+
const adapter = (mcpHeroOptions, baseContext) => {
|
|
69
|
+
_options = mcpHeroOptions;
|
|
70
|
+
_context = baseContext.fork({ adapter: "vercel" });
|
|
71
|
+
return {
|
|
72
|
+
context: _context,
|
|
73
|
+
start: async (actions) => {
|
|
74
|
+
_actions = actions;
|
|
75
|
+
_readyResolve();
|
|
76
|
+
},
|
|
77
|
+
stop: async () => {
|
|
78
|
+
_actions = [];
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
return {
|
|
83
|
+
adapter,
|
|
84
|
+
handler: handleRequest,
|
|
85
|
+
GET: handleRequest,
|
|
86
|
+
POST: handleRequest,
|
|
87
|
+
DELETE: handleRequest
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export {
|
|
91
|
+
vercel
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapter/vercel.ts"],"sourcesContent":["import { Action, AdapterGenerator, MCPHeroContext, MCPHeroOptions, toolResponse } from '@mcphero/core'\nimport { createLogger } from '@mcphero/logger'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js'\nimport { capitalCase, pascalCase } from 'change-case'\n\nexport interface VercelAdapterOptions {\n enableJsonResponse?: boolean\n}\n\nexport interface VercelAdapter {\n adapter: AdapterGenerator\n handler: (request: Request) => Promise<Response>\n GET: (request: Request) => Promise<Response>\n POST: (request: Request) => Promise<Response>\n DELETE: (request: Request) => Promise<Response>\n}\n\nexport function vercel(options: VercelAdapterOptions = {}): VercelAdapter {\n let _actions: Action[] = []\n let _options: MCPHeroOptions | null = null\n let _context: MCPHeroContext | null = null\n let _readyResolve: () => void\n const _ready = new Promise<void>((resolve) => {\n _readyResolve = resolve\n })\n\n const handleRequest = async (request: Request): Promise<Response> => {\n await _ready\n\n const transport = new WebStandardStreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n enableJsonResponse: options.enableJsonResponse\n })\n\n const server = new McpServer({\n name: _options!.name,\n description: _options!.description,\n version: _options!.version\n }, {\n capabilities: { tools: {}, logging: {} }\n })\n\n for (const action of _actions) {\n server.registerTool(pascalCase(action.name), {\n title: capitalCase(action.name),\n description: action.description,\n inputSchema: action.input\n }, async (input, extra) => {\n const logger = createLogger({\n stream: process.stderr,\n onLog: (level, data) => {\n extra.sendNotification({ method: 'notifications/message', params: { level, data } })\n },\n onProgress: ({ progress, total, message }) => {\n if (!extra._meta?.progressToken) { return }\n extra.sendNotification({\n method: 'notifications/progress',\n params: {\n progress,\n total,\n message,\n progressToken: extra._meta.progressToken\n }\n })\n }\n })\n return action.run(input, _context!.fork({ logger, extra })).then((result) => {\n return toolResponse(result)\n }).catch((error) => {\n if (error instanceof Error) {\n return toolResponse({ success: false, name: error.name, message: error.message, stack: error.stack })\n } else {\n return toolResponse({ success: false, name: 'Unknown Error', message: 'An unknown error occured', error })\n }\n })\n })\n }\n\n await server.connect(transport)\n return transport.handleRequest(request)\n }\n\n const adapter: AdapterGenerator = (mcpHeroOptions: MCPHeroOptions, baseContext: MCPHeroContext) => {\n _options = mcpHeroOptions\n _context = baseContext.fork({ adapter: 'vercel' })\n return {\n context: _context,\n start: async (actions) => {\n _actions = actions\n _readyResolve()\n },\n stop: async () => {\n _actions = []\n }\n }\n }\n\n return {\n adapter,\n handler: handleRequest,\n GET: handleRequest,\n POST: handleRequest,\n DELETE: handleRequest\n }\n}\n"],"mappings":";AAAA,SAAmE,oBAAoB;AACvF,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAC1B,SAAS,gDAAgD;AACzD,SAAS,aAAa,kBAAkB;AAcjC,SAAS,OAAO,UAAgC,CAAC,GAAkB;AACxE,MAAI,WAAqB,CAAC;AAC1B,MAAI,WAAkC;AACtC,MAAI,WAAkC;AACtC,MAAI;AACJ,QAAM,SAAS,IAAI,QAAc,CAAC,YAAY;AAC5C,oBAAgB;AAAA,EAClB,CAAC;AAED,QAAM,gBAAgB,OAAO,YAAwC;AACnE,UAAM;AAEN,UAAM,YAAY,IAAI,yCAAyC;AAAA,MAC7D,oBAAoB;AAAA,MACpB,oBAAoB,QAAQ;AAAA,IAC9B,CAAC;AAED,UAAM,SAAS,IAAI,UAAU;AAAA,MAC3B,MAAM,SAAU;AAAA,MAChB,aAAa,SAAU;AAAA,MACvB,SAAS,SAAU;AAAA,IACrB,GAAG;AAAA,MACD,cAAc,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,EAAE;AAAA,IACzC,CAAC;AAED,eAAW,UAAU,UAAU;AAC7B,aAAO,aAAa,WAAW,OAAO,IAAI,GAAG;AAAA,QAC3C,OAAO,YAAY,OAAO,IAAI;AAAA,QAC9B,aAAa,OAAO;AAAA,QACpB,aAAa,OAAO;AAAA,MACtB,GAAG,OAAO,OAAO,UAAU;AACzB,cAAM,SAAS,aAAa;AAAA,UAC1B,QAAQ,QAAQ;AAAA,UAChB,OAAO,CAAC,OAAO,SAAS;AACtB,kBAAM,iBAAiB,EAAE,QAAQ,yBAAyB,QAAQ,EAAE,OAAO,KAAK,EAAE,CAAC;AAAA,UACrF;AAAA,UACA,YAAY,CAAC,EAAE,UAAU,OAAO,QAAQ,MAAM;AAC5C,gBAAI,CAAC,MAAM,OAAO,eAAe;AAAE;AAAA,YAAO;AAC1C,kBAAM,iBAAiB;AAAA,cACrB,QAAQ;AAAA,cACR,QAAQ;AAAA,gBACN;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,eAAe,MAAM,MAAM;AAAA,cAC7B;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF,CAAC;AACD,eAAO,OAAO,IAAI,OAAO,SAAU,KAAK,EAAE,QAAQ,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW;AAC3E,iBAAO,aAAa,MAAM;AAAA,QAC5B,CAAC,EAAE,MAAM,CAAC,UAAU;AAClB,cAAI,iBAAiB,OAAO;AAC1B,mBAAO,aAAa,EAAE,SAAS,OAAO,MAAM,MAAM,MAAM,SAAS,MAAM,SAAS,OAAO,MAAM,MAAM,CAAC;AAAA,UACtG,OAAO;AACL,mBAAO,aAAa,EAAE,SAAS,OAAO,MAAM,iBAAiB,SAAS,4BAA4B,MAAM,CAAC;AAAA,UAC3G;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACH;AAEA,UAAM,OAAO,QAAQ,SAAS;AAC9B,WAAO,UAAU,cAAc,OAAO;AAAA,EACxC;AAEA,QAAM,UAA4B,CAAC,gBAAgC,gBAAgC;AACjG,eAAW;AACX,eAAW,YAAY,KAAK,EAAE,SAAS,SAAS,CAAC;AACjD,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO,OAAO,YAAY;AACxB,mBAAW;AACX,sBAAc;AAAA,MAChB;AAAA,MACA,MAAM,YAAY;AAChB,mBAAW,CAAC;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,SAAS;AAAA,IACT,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EACV;AACF;","names":[]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import eslint from '@eslint/js'
|
|
2
|
+
import stylistic from '@stylistic/eslint-plugin'
|
|
3
|
+
import { defineConfig } from 'eslint/config'
|
|
4
|
+
import tseslint from 'typescript-eslint'
|
|
5
|
+
|
|
6
|
+
export default defineConfig(eslint.configs.recommended, tseslint.configs.recommendedTypeChecked, tseslint.configs.stylisticTypeChecked, {
|
|
7
|
+
languageOptions: {
|
|
8
|
+
parserOptions: {
|
|
9
|
+
project: 'tsconfig.json',
|
|
10
|
+
tsconfigRootDir: import.meta.dirname
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
plugins: { '@stylistic': stylistic },
|
|
14
|
+
rules: {
|
|
15
|
+
'@stylistic/space-in-parens': ['error'],
|
|
16
|
+
'@stylistic/comma-spacing': ['error'],
|
|
17
|
+
'@stylistic/no-multi-spaces': ['error'],
|
|
18
|
+
'@stylistic/no-trailing-spaces': ['error'],
|
|
19
|
+
'@stylistic/no-whitespace-before-property': ['error'],
|
|
20
|
+
'@stylistic/array-bracket-newline': ['error', 'consistent'],
|
|
21
|
+
'@stylistic/array-bracket-spacing': ['error'],
|
|
22
|
+
'@stylistic/arrow-spacing': ['error'],
|
|
23
|
+
'@stylistic/arrow-parens': ['error', 'always'],
|
|
24
|
+
'@stylistic/block-spacing': ['error', 'always'],
|
|
25
|
+
'@stylistic/brace-style': ['error', '1tbs', { 'allowSingleLine': true }],
|
|
26
|
+
'@stylistic/comma-dangle': ['error', 'never'],
|
|
27
|
+
'@stylistic/key-spacing': ['error'],
|
|
28
|
+
'@stylistic/keyword-spacing': ['error'],
|
|
29
|
+
'@stylistic/member-delimiter-style': ['error', { 'multiline': { 'delimiter': 'none' } }],
|
|
30
|
+
'@stylistic/no-extra-semi': ['error'],
|
|
31
|
+
'@stylistic/indent': ['error', 2],
|
|
32
|
+
'@stylistic/no-multiple-empty-lines': ['error', { 'max': 1, 'maxEOF': 0, 'maxBOF': 0 }],
|
|
33
|
+
'@stylistic/object-curly-spacing': ['error', 'always'],
|
|
34
|
+
'@stylistic/quotes': ['error', 'single'],
|
|
35
|
+
'@stylistic/semi': ['error', 'never'],
|
|
36
|
+
'@stylistic/space-before-blocks': ['error', 'always'],
|
|
37
|
+
'@stylistic/space-before-function-paren': ['error', { 'anonymous': 'always', 'named': 'never', 'asyncArrow': 'always' }],
|
|
38
|
+
'@typescript-eslint/adjacent-overload-signatures': 'error',
|
|
39
|
+
'@typescript-eslint/array-type': 'off',
|
|
40
|
+
'@typescript-eslint/await-thenable': 'error',
|
|
41
|
+
'@typescript-eslint/ban-types': 'off',
|
|
42
|
+
'@typescript-eslint/consistent-type-assertions': 'off',
|
|
43
|
+
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
44
|
+
'@typescript-eslint/explicit-member-accessibility': 'off',
|
|
45
|
+
'@typescript-eslint/no-angle-bracket-type-assertion': 'off',
|
|
46
|
+
'@typescript-eslint/no-empty-function': 'off',
|
|
47
|
+
'@typescript-eslint/no-empty-interface': 'off',
|
|
48
|
+
'@typescript-eslint/no-extra-non-null-assertion': 'error',
|
|
49
|
+
'@typescript-eslint/no-floating-promises': 'off',
|
|
50
|
+
'@typescript-eslint/no-misused-new': 'error',
|
|
51
|
+
'@typescript-eslint/no-misused-promises': 'off',
|
|
52
|
+
'@typescript-eslint/no-namespace': 'off',
|
|
53
|
+
'@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
|
|
54
|
+
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
55
|
+
'@typescript-eslint/no-object-literal-type-assertion': 'off',
|
|
56
|
+
'@typescript-eslint/no-parameter-properties': 'off',
|
|
57
|
+
'@typescript-eslint/no-shadow': 'error',
|
|
58
|
+
'@typescript-eslint/no-triple-slash-reference': 'off',
|
|
59
|
+
'@typescript-eslint/no-unused-vars': ['error', {
|
|
60
|
+
'args': 'all',
|
|
61
|
+
'argsIgnorePattern': '^_',
|
|
62
|
+
'caughtErrors': 'all',
|
|
63
|
+
'caughtErrorsIgnorePattern': '^_',
|
|
64
|
+
'destructuredArrayIgnorePattern': '^_',
|
|
65
|
+
'varsIgnorePattern': '^_',
|
|
66
|
+
'ignoreRestSiblings': true
|
|
67
|
+
}],
|
|
68
|
+
'@typescript-eslint/no-use-before-define': 'off',
|
|
69
|
+
'@typescript-eslint/no-var-requires': 'off',
|
|
70
|
+
'@typescript-eslint/prefer-for-of': 'error',
|
|
71
|
+
'@typescript-eslint/prefer-interface': 'off',
|
|
72
|
+
'@typescript-eslint/prefer-nullish-coalescing': 'off',
|
|
73
|
+
'@typescript-eslint/prefer-optional-chain': 'error',
|
|
74
|
+
'@typescript-eslint/return-await': 'error',
|
|
75
|
+
'@typescript-eslint/unified-signatures': 'error',
|
|
76
|
+
'@typescript-eslint/no-unsafe-return': 'off',
|
|
77
|
+
'@typescript-eslint/no-redundant-type-constituents': 'off',
|
|
78
|
+
'@typescript-eslint/no-unsafe-member-access': 'off',
|
|
79
|
+
'@typescript-eslint/no-unsafe-call': 'off',
|
|
80
|
+
'@typescript-eslint/no-unsafe-argument': 'off',
|
|
81
|
+
'@typescript-eslint/no-unsafe-assignment': 'off',
|
|
82
|
+
'@typescript-eslint/dot-notation': 'off',
|
|
83
|
+
'@typescript-eslint/prefer-regexp-exec': 'off',
|
|
84
|
+
'@typescript-eslint/require-await': 'off',
|
|
85
|
+
'@typescript-eslint/only-throw-error': ['error', {
|
|
86
|
+
'allow': [
|
|
87
|
+
{ from: 'package', name: 'TypedResponse', package: '@remix-run/server-runtime' },
|
|
88
|
+
{ from: 'lib', name: 'Response' }
|
|
89
|
+
]
|
|
90
|
+
}],
|
|
91
|
+
'@typescript-eslint/no-base-to-string': 'off',
|
|
92
|
+
'@typescript-eslint/restrict-template-expressions': 'off'
|
|
93
|
+
}
|
|
94
|
+
}, {
|
|
95
|
+
files: ['eslint.config.mjs'],
|
|
96
|
+
extends: [tseslint.configs.disableTypeChecked]
|
|
97
|
+
}, {
|
|
98
|
+
ignores: ['build', 'tsup.config.ts']
|
|
99
|
+
})
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcphero/vercel",
|
|
3
|
+
"version": "1.1.6",
|
|
4
|
+
"description": "MCP Hero Vercel Serverless Adapter",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+ssh://git@github.com/atomicbi/mcphero.git",
|
|
8
|
+
"directory": "packages/vercel"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "build/index.js",
|
|
12
|
+
"types": "build/index.d.ts",
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
15
|
+
"change-case": "^5.4.4",
|
|
16
|
+
"zod": "^4.3.6",
|
|
17
|
+
"@mcphero/core": "1.1.6",
|
|
18
|
+
"@mcphero/logger": "1.1.6"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@eslint/js": "^10.0.1",
|
|
22
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
23
|
+
"@types/node": "^22.0.0",
|
|
24
|
+
"rimraf": "^6.1.3",
|
|
25
|
+
"tsup": "^8.5.1",
|
|
26
|
+
"tsx": "^4.21.0",
|
|
27
|
+
"typescript": "^5.9.3",
|
|
28
|
+
"typescript-eslint": "^8.56.1"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"clean": "rimraf build",
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"watch": "tsup --watch",
|
|
34
|
+
"typecheck": "tsc --noEmit",
|
|
35
|
+
"lint": "eslint",
|
|
36
|
+
"check": "pnpm lint && pnpm typecheck"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Action, AdapterGenerator, MCPHeroContext, MCPHeroOptions, toolResponse } from '@mcphero/core'
|
|
2
|
+
import { createLogger } from '@mcphero/logger'
|
|
3
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
4
|
+
import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js'
|
|
5
|
+
import { capitalCase, pascalCase } from 'change-case'
|
|
6
|
+
|
|
7
|
+
export interface VercelAdapterOptions {
|
|
8
|
+
enableJsonResponse?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface VercelAdapter {
|
|
12
|
+
adapter: AdapterGenerator
|
|
13
|
+
handler: (request: Request) => Promise<Response>
|
|
14
|
+
GET: (request: Request) => Promise<Response>
|
|
15
|
+
POST: (request: Request) => Promise<Response>
|
|
16
|
+
DELETE: (request: Request) => Promise<Response>
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function vercel(options: VercelAdapterOptions = {}): VercelAdapter {
|
|
20
|
+
let _actions: Action[] = []
|
|
21
|
+
let _options: MCPHeroOptions | null = null
|
|
22
|
+
let _context: MCPHeroContext | null = null
|
|
23
|
+
let _readyResolve: () => void
|
|
24
|
+
const _ready = new Promise<void>((resolve) => {
|
|
25
|
+
_readyResolve = resolve
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const handleRequest = async (request: Request): Promise<Response> => {
|
|
29
|
+
await _ready
|
|
30
|
+
|
|
31
|
+
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
32
|
+
sessionIdGenerator: undefined,
|
|
33
|
+
enableJsonResponse: options.enableJsonResponse
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const server = new McpServer({
|
|
37
|
+
name: _options!.name,
|
|
38
|
+
description: _options!.description,
|
|
39
|
+
version: _options!.version
|
|
40
|
+
}, {
|
|
41
|
+
capabilities: { tools: {}, logging: {} }
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
for (const action of _actions) {
|
|
45
|
+
server.registerTool(pascalCase(action.name), {
|
|
46
|
+
title: capitalCase(action.name),
|
|
47
|
+
description: action.description,
|
|
48
|
+
inputSchema: action.input
|
|
49
|
+
}, async (input, extra) => {
|
|
50
|
+
const logger = createLogger({
|
|
51
|
+
stream: process.stderr,
|
|
52
|
+
onLog: (level, data) => {
|
|
53
|
+
extra.sendNotification({ method: 'notifications/message', params: { level, data } })
|
|
54
|
+
},
|
|
55
|
+
onProgress: ({ progress, total, message }) => {
|
|
56
|
+
if (!extra._meta?.progressToken) { return }
|
|
57
|
+
extra.sendNotification({
|
|
58
|
+
method: 'notifications/progress',
|
|
59
|
+
params: {
|
|
60
|
+
progress,
|
|
61
|
+
total,
|
|
62
|
+
message,
|
|
63
|
+
progressToken: extra._meta.progressToken
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
return action.run(input, _context!.fork({ logger, extra })).then((result) => {
|
|
69
|
+
return toolResponse(result)
|
|
70
|
+
}).catch((error) => {
|
|
71
|
+
if (error instanceof Error) {
|
|
72
|
+
return toolResponse({ success: false, name: error.name, message: error.message, stack: error.stack })
|
|
73
|
+
} else {
|
|
74
|
+
return toolResponse({ success: false, name: 'Unknown Error', message: 'An unknown error occured', error })
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
await server.connect(transport)
|
|
81
|
+
return transport.handleRequest(request)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const adapter: AdapterGenerator = (mcpHeroOptions: MCPHeroOptions, baseContext: MCPHeroContext) => {
|
|
85
|
+
_options = mcpHeroOptions
|
|
86
|
+
_context = baseContext.fork({ adapter: 'vercel' })
|
|
87
|
+
return {
|
|
88
|
+
context: _context,
|
|
89
|
+
start: async (actions) => {
|
|
90
|
+
_actions = actions
|
|
91
|
+
_readyResolve()
|
|
92
|
+
},
|
|
93
|
+
stop: async () => {
|
|
94
|
+
_actions = []
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
adapter,
|
|
101
|
+
handler: handleRequest,
|
|
102
|
+
GET: handleRequest,
|
|
103
|
+
POST: handleRequest,
|
|
104
|
+
DELETE: handleRequest
|
|
105
|
+
}
|
|
106
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './adapter/vercel.js'
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"lib": ["ESNext"],
|
|
7
|
+
"outDir": "build",
|
|
8
|
+
"rootDir": ".",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"allowSyntheticDefaultImports": true,
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"declaration": true,
|
|
16
|
+
"declarationMap": true,
|
|
17
|
+
"sourceMap": true
|
|
18
|
+
},
|
|
19
|
+
"include": ["src"],
|
|
20
|
+
"exclude": ["node_modules", "build"]
|
|
21
|
+
}
|
package/tsup.config.ts
ADDED