@forwardemail/mcp-server 1.0.4 → 1.0.5

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
@@ -0,0 +1 @@
1
+ # <https://forwardemail.net/mcp>
package/bin/mcp-server.js CHANGED
@@ -2,4 +2,8 @@
2
2
  const {McpServer} = require('../lib/index.js');
3
3
 
4
4
  const server = new McpServer();
5
- server.listen();
5
+ // eslint-disable-next-line unicorn/prefer-top-level-await
6
+ server.listen().catch((error) => {
7
+ console.error('Server error:', error);
8
+ process.exit(1);
9
+ });
package/lib/index.js CHANGED
@@ -1,62 +1,66 @@
1
- const readline = require('node:readline');
1
+ const {Server} = require('@modelcontextprotocol/sdk/server/index.js');
2
+ const {
3
+ StdioServerTransport,
4
+ } = require('@modelcontextprotocol/sdk/server/stdio.js');
5
+ const {
6
+ ListToolsRequestSchema,
7
+ CallToolRequestSchema,
8
+ } = require('@modelcontextprotocol/sdk/types.js');
9
+ const {name, version} = require('../package.json');
2
10
  const {getTools} = require('./tools.js');
3
11
 
4
12
  class McpServer {
5
13
  constructor(options = {}) {
6
14
  this.tools = getTools(options);
7
- this.rl = readline.createInterface({
8
- input: process.stdin,
9
- output: process.stdout,
10
- terminal: false,
11
- });
12
- }
15
+ this.server = new Server({name, version}, {capabilities: {tools: {}}});
16
+
17
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
18
+ tools: Object.values(this.tools).map((tool) => ({
19
+ name: tool.toolSpec.name,
20
+ description: tool.toolSpec.description,
21
+ inputSchema: {
22
+ type: 'object',
23
+ properties: tool.toolSpec.input?.properties ?? {},
24
+ },
25
+ })),
26
+ }));
27
+
28
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
29
+ const toolName = request.params?.name;
30
+ const tool = this.tools[toolName];
31
+ if (!tool) {
32
+ return {
33
+ content: [{type: 'text', text: `Tool not found: ${toolName}`}],
34
+ isError: true,
35
+ };
36
+ }
13
37
 
14
- listen() {
15
- this.rl.on('line', async (line) => {
16
38
  try {
17
- const request = JSON.parse(line);
18
- await this.handleRequest(request);
39
+ const result = await tool.invoke(request.params?.arguments ?? {});
40
+ return {
41
+ content: [
42
+ {
43
+ type: 'text',
44
+ text:
45
+ typeof result === 'string'
46
+ ? result
47
+ : JSON.stringify(result, null, 2),
48
+ },
49
+ ],
50
+ };
19
51
  } catch (error) {
20
- this.sendError(error.message);
52
+ const errorMessage = error.response?.data?.message || error.message;
53
+ return {
54
+ content: [{type: 'text', text: errorMessage}],
55
+ isError: true,
56
+ };
21
57
  }
22
58
  });
23
59
  }
24
60
 
25
- async handleRequest(request) {
26
- if (request.type === 'listTools') {
27
- return this.sendResponse(request.id, {
28
- tools: Object.values(this.tools).map((tool) => tool.toolSpec),
29
- });
30
- }
31
-
32
- if (request.type === 'invokeTool') {
33
- const tool = this.tools[request.name];
34
- if (tool) {
35
- try {
36
- const result = await tool.invoke(request.arguments);
37
- return this.sendResponse(request.id, {result});
38
- } catch (error) {
39
- const errorMessage = error.response?.data?.message || error.message;
40
- return this.sendError(errorMessage, request.id);
41
- }
42
- }
43
-
44
- return this.sendError(`Tool not found: ${request.name}`, request.id);
45
- }
46
-
47
- return this.sendError(`Unknown request type: ${request.type}`, request.id);
48
- }
49
-
50
- sendResponse(id, payload) {
51
- this.send({type: 'toolResponse', id, ...payload});
52
- }
53
-
54
- sendError(message, id = null) {
55
- this.send({type: 'error', id, message});
56
- }
57
-
58
- send(data) {
59
- process.stdout.write(JSON.stringify(data) + '\n');
61
+ async listen() {
62
+ const transport = new StdioServerTransport();
63
+ await this.server.connect(transport);
60
64
  }
61
65
  }
62
66
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@forwardemail/mcp-server",
3
3
  "description": "Model Context Protocol (MCP) server for Forward Email. Connect AI to your inbox.",
4
- "version": "1.0.4",
4
+ "version": "1.0.5",
5
5
  "author": "Forward Email LLC <support@forwardemail.net> (https://forwardemail.net)",
6
6
  "bin": {
7
7
  "mcp-server": "bin/mcp-server.js"
@@ -10,6 +10,7 @@
10
10
  "url": "https://github.com/forwardemail/mcp-server/issues"
11
11
  },
12
12
  "dependencies": {
13
+ "@modelcontextprotocol/sdk": "^1.27.1",
13
14
  "axios": "^1.7.2"
14
15
  },
15
16
  "devDependencies": {
@@ -54,6 +55,7 @@
54
55
  ],
55
56
  "license": "BUSL-1.1",
56
57
  "main": "lib/index.js",
58
+ "packageManager": "pnpm@9.0.0",
57
59
  "prettier": {
58
60
  "useTabs": false,
59
61
  "tabWidth": 2,
@@ -66,6 +68,13 @@
66
68
  "type": "git",
67
69
  "url": "git+https://github.com/forwardemail/mcp-server.git"
68
70
  },
71
+ "scripts": {
72
+ "lint": "fixpack && remark . -qfo && xo --fix",
73
+ "pre-commit": "lint-staged",
74
+ "prepare": "husky",
75
+ "pretest": "pnpm run lint",
76
+ "test": "c8 --reporter=text --reporter=html node --test"
77
+ },
69
78
  "types": "lib/index.d.ts",
70
79
  "xo": {
71
80
  "space": 2,
@@ -81,11 +90,5 @@
81
90
  }
82
91
  ]
83
92
  }
84
- },
85
- "scripts": {
86
- "lint": "fixpack && remark . -qfo && xo --fix",
87
- "pre-commit": "lint-staged",
88
- "pretest": "pnpm run lint",
89
- "test": "c8 --reporter=text --reporter=html node --test"
90
93
  }
91
- }
94
+ }