@myatkyawthu/mcp-connect 0.3.0 → 0.3.2
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/CHANGELOG.md +71 -0
- package/package.json +2 -1
- package/src/server/mcpServer.js +2 -1
- package/src/utils/configValidation.js +3 -2
- package/src/utils/validation.js +34 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@myatkyawthu/mcp-connect` are documented here.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## [0.3.2] — 2026-07-22
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **Config validation: destructured args no longer falsely error**
|
|
12
|
+
Tools with handlers like `async ({ id, content }) => ...` were incorrectly reported as having multiple parameters. The validator now detects destructured arguments (`{...}` or `[...]`) and counts them as a single parameter. ([`configValidation.js`](src/utils/configValidation.js))
|
|
13
|
+
|
|
14
|
+
- **Config validation: `confirm` no longer warns as unknown property**
|
|
15
|
+
Tools with `confirm: true` were emitting a spurious _"Unknown properties: confirm"_ warning. `confirm` is now a recognised property in the validator. ([`configValidation.js`](src/utils/configValidation.js))
|
|
16
|
+
|
|
17
|
+
### New Features
|
|
18
|
+
|
|
19
|
+
- **Runtime schema validation against tool input schemas**
|
|
20
|
+
Tool arguments are now validated against the tool's declared JSON Schema before the handler is called. Required fields that are missing and properties with the wrong type both return a clear error to the AI client instead of silently crashing.
|
|
21
|
+
- No new dependencies — uses the existing `required` and `properties.*.type` fields you already define.
|
|
22
|
+
- Example error: `Missing required argument: "message"` or `Argument "limit" must be of type number, got string`
|
|
23
|
+
([`validation.js`](src/utils/validation.js), [`mcpServer.js`](src/server/mcpServer.js))
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## [0.3.1] — 2026-07-21
|
|
28
|
+
|
|
29
|
+
### Patch
|
|
30
|
+
|
|
31
|
+
- Re-publish to fix `bin` field packaging issue in 0.3.0 that caused the `mcp-connect` CLI command not to register on some npm versions.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## [0.3.0] — 2026-07-21
|
|
36
|
+
|
|
37
|
+
### Breaking Changes
|
|
38
|
+
|
|
39
|
+
- **Removed Resources and Prompts support** — the framework is now strictly tool-centric. If you were using `resources` or `prompts` in your config, remove them. This makes the API surface smaller and the codebase ~40% leaner (YAGNI).
|
|
40
|
+
|
|
41
|
+
### New Features
|
|
42
|
+
|
|
43
|
+
- **SSE / HTTP transport** (`--port` flag) — expose your MCP server over HTTP to any web client, IDE, or AI tool that supports SSE transport (Cursor, Cline, Windsurf, Claude.ai web, etc.)
|
|
44
|
+
- **Tunnel / relay transport** (`--tunnel` flag) — NAT-bypassing outbound tunnel so your laptop can serve remote AI clients without an open port. Includes a self-hostable `MCPRelayServer`.
|
|
45
|
+
- **Inspector Dashboard** — live browser UI at `GET /` showing real-time tool call logs and a mock tool executor for debugging without an AI client.
|
|
46
|
+
- **Bearer token auth** — protect all endpoints via `MCP_TUNNEL_TOKEN` env var or `server.tunnel.token` config.
|
|
47
|
+
- **CORS origin allowlist** — lock down which origins can connect via `server.cors.origins`.
|
|
48
|
+
- **Confirm gate** — mark any tool `confirm: true` to require a `y/N` prompt in the terminal before execution. Uses `/dev/tty` directly so it doesn't interfere with the STDIO JSON-RPC pipe.
|
|
49
|
+
- **AES-256-GCM end-to-end encryption** — tunnel payloads can be encrypted before leaving your machine via `server.tunnel.encryptionKey`.
|
|
50
|
+
|
|
51
|
+
### Built-in Protections (always on)
|
|
52
|
+
|
|
53
|
+
- Rate limiting: 100 requests/minute
|
|
54
|
+
- Tool timeout: 30 seconds
|
|
55
|
+
- Response size cap: 1MB
|
|
56
|
+
- Error sanitization: stack traces stripped before returning to AI clients
|
|
57
|
+
- Circular reference guard on JSON serialisation
|
|
58
|
+
|
|
59
|
+
### Upgraded
|
|
60
|
+
|
|
61
|
+
- `@modelcontextprotocol/sdk` upgraded from `^0.5.x` to `^1.29.0`
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## [0.2.0] — Earlier
|
|
66
|
+
|
|
67
|
+
- Added basic SSE transport and dashboard prototype.
|
|
68
|
+
|
|
69
|
+
## [0.1.0] — Initial release
|
|
70
|
+
|
|
71
|
+
- STDIO-only MCP wrapper with `defineMCP()` config API.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myatkyawthu/mcp-connect",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Dead simple MCP (Model Context Protocol) server for exposing your app functions to AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"files": [
|
|
14
14
|
"src",
|
|
15
15
|
"README.md",
|
|
16
|
+
"CHANGELOG.md",
|
|
16
17
|
"LICENSE"
|
|
17
18
|
],
|
|
18
19
|
"scripts": {
|
package/src/server/mcpServer.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import { createServer } from 'node:http';
|
|
9
9
|
import { decrypt, encrypt } from '../utils/crypto.js';
|
|
10
10
|
import { logger } from '../utils/logger.js';
|
|
11
|
-
import { sanitizeErrorMessage, validateToolArguments } from '../utils/validation.js';
|
|
11
|
+
import { sanitizeErrorMessage, validateArgsAgainstSchema, validateToolArguments } from '../utils/validation.js';
|
|
12
12
|
import { getDashboardHTML } from './dashboard.js';
|
|
13
13
|
|
|
14
14
|
const DEFAULT_TOOL_TIMEOUT = 30000;
|
|
@@ -150,6 +150,7 @@ export class MCPConnectServer {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
const validatedArgs = validateToolArguments(args);
|
|
153
|
+
validateArgsAgainstSchema(validatedArgs, tool.inputSchema);
|
|
153
154
|
|
|
154
155
|
const toolPromise = Promise.resolve(tool.handler(validatedArgs));
|
|
155
156
|
const result = await logger.timeAsync(
|
|
@@ -211,7 +211,7 @@ export class ConfigValidator {
|
|
|
211
211
|
this.validateToolDescription(tool.description, `${fieldPrefix}.description`);
|
|
212
212
|
this.validateToolSchema(tool.schema, `${fieldPrefix}.schema`);
|
|
213
213
|
|
|
214
|
-
const knownProps = ['name', 'handler', 'description', 'schema'];
|
|
214
|
+
const knownProps = ['name', 'handler', 'description', 'schema', 'confirm'];
|
|
215
215
|
const unknownProps = Object.keys(tool).filter((prop) => !knownProps.includes(prop));
|
|
216
216
|
if (unknownProps.length > 0) {
|
|
217
217
|
this.addWarning(
|
|
@@ -290,7 +290,8 @@ export class ConfigValidator {
|
|
|
290
290
|
if (paramMatch) {
|
|
291
291
|
const params = paramMatch[1].trim();
|
|
292
292
|
if (params) {
|
|
293
|
-
const
|
|
293
|
+
const isDestructured = params.startsWith('{') || params.startsWith('[');
|
|
294
|
+
const paramCount = isDestructured ? 1 : params.split(',').filter((p) => p.trim()).length;
|
|
294
295
|
if (paramCount > 1) {
|
|
295
296
|
this.addError(
|
|
296
297
|
fieldPath,
|
package/src/utils/validation.js
CHANGED
|
@@ -36,6 +36,40 @@ export function validateToolArguments(args) {
|
|
|
36
36
|
return args;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Validate args against a JSON Schema definition (subset: required + type).
|
|
41
|
+
* No external deps — covers the common cases without pulling in ajv.
|
|
42
|
+
* @param {object} args
|
|
43
|
+
* @param {object} schema - the tool's inputSchema
|
|
44
|
+
*/
|
|
45
|
+
export function validateArgsAgainstSchema(args, schema) {
|
|
46
|
+
if (!schema || typeof schema !== 'object') return;
|
|
47
|
+
|
|
48
|
+
// Check required fields
|
|
49
|
+
if (Array.isArray(schema.required)) {
|
|
50
|
+
for (const field of schema.required) {
|
|
51
|
+
if (args[field] === undefined || args[field] === null) {
|
|
52
|
+
throw new Error(`Missing required argument: "${field}"`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Check declared property types
|
|
58
|
+
if (schema.properties && typeof schema.properties === 'object') {
|
|
59
|
+
for (const [key, def] of Object.entries(schema.properties)) {
|
|
60
|
+
if (args[key] === undefined) continue; // optional — already handled above
|
|
61
|
+
if (!def || typeof def.type !== 'string') continue;
|
|
62
|
+
|
|
63
|
+
const actual = Array.isArray(args[key]) ? 'array' : typeof args[key];
|
|
64
|
+
if (actual !== def.type) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Argument "${key}" must be of type ${def.type}, got ${actual}`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
39
73
|
export function sanitizeErrorMessage(error) {
|
|
40
74
|
if (error instanceof Error) {
|
|
41
75
|
// Remove sensitive information from stack traces
|