mcp-recon 0.2.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/LICENSE +19 -0
- package/README.md +271 -0
- package/dist/bin/recon.d.ts +18 -0
- package/dist/bin/recon.d.ts.map +1 -0
- package/dist/bin/recon.js +361 -0
- package/dist/bin/recon.js.map +1 -0
- package/dist/caveats/index.d.ts +46 -0
- package/dist/caveats/index.d.ts.map +1 -0
- package/dist/caveats/index.js +186 -0
- package/dist/caveats/index.js.map +1 -0
- package/dist/caveats/render.d.ts +25 -0
- package/dist/caveats/render.d.ts.map +1 -0
- package/dist/caveats/render.js +100 -0
- package/dist/caveats/render.js.map +1 -0
- package/dist/caveats/types.d.ts +94 -0
- package/dist/caveats/types.d.ts.map +1 -0
- package/dist/caveats/types.js +17 -0
- package/dist/caveats/types.js.map +1 -0
- package/dist/classify/caveat.d.ts +29 -0
- package/dist/classify/caveat.d.ts.map +1 -0
- package/dist/classify/caveat.js +103 -0
- package/dist/classify/caveat.js.map +1 -0
- package/dist/classify/index.d.ts +21 -0
- package/dist/classify/index.d.ts.map +1 -0
- package/dist/classify/index.js +186 -0
- package/dist/classify/index.js.map +1 -0
- package/dist/classify/rules.d.ts +62 -0
- package/dist/classify/rules.d.ts.map +1 -0
- package/dist/classify/rules.js +219 -0
- package/dist/classify/rules.js.map +1 -0
- package/dist/classify/types.d.ts +45 -0
- package/dist/classify/types.d.ts.map +1 -0
- package/dist/classify/types.js +9 -0
- package/dist/classify/types.js.map +1 -0
- package/dist/enumerate.d.ts +79 -0
- package/dist/enumerate.d.ts.map +1 -0
- package/dist/enumerate.js +62 -0
- package/dist/enumerate.js.map +1 -0
- package/dist/fuzz/axes/boundary.d.ts +17 -0
- package/dist/fuzz/axes/boundary.d.ts.map +1 -0
- package/dist/fuzz/axes/boundary.js +143 -0
- package/dist/fuzz/axes/boundary.js.map +1 -0
- package/dist/fuzz/axes/encoding.d.ts +17 -0
- package/dist/fuzz/axes/encoding.d.ts.map +1 -0
- package/dist/fuzz/axes/encoding.js +59 -0
- package/dist/fuzz/axes/encoding.js.map +1 -0
- package/dist/fuzz/axes/path-traversal.d.ts +17 -0
- package/dist/fuzz/axes/path-traversal.d.ts.map +1 -0
- package/dist/fuzz/axes/path-traversal.js +56 -0
- package/dist/fuzz/axes/path-traversal.js.map +1 -0
- package/dist/fuzz/axes/schema-violation.d.ts +18 -0
- package/dist/fuzz/axes/schema-violation.d.ts.map +1 -0
- package/dist/fuzz/axes/schema-violation.js +74 -0
- package/dist/fuzz/axes/schema-violation.js.map +1 -0
- package/dist/fuzz/axes/type-confusion.d.ts +17 -0
- package/dist/fuzz/axes/type-confusion.d.ts.map +1 -0
- package/dist/fuzz/axes/type-confusion.js +67 -0
- package/dist/fuzz/axes/type-confusion.js.map +1 -0
- package/dist/fuzz/axes/url-hostility.d.ts +17 -0
- package/dist/fuzz/axes/url-hostility.d.ts.map +1 -0
- package/dist/fuzz/axes/url-hostility.js +61 -0
- package/dist/fuzz/axes/url-hostility.js.map +1 -0
- package/dist/fuzz/index.d.ts +41 -0
- package/dist/fuzz/index.d.ts.map +1 -0
- package/dist/fuzz/index.js +147 -0
- package/dist/fuzz/index.js.map +1 -0
- package/dist/fuzz/prng.d.ts +26 -0
- package/dist/fuzz/prng.d.ts.map +1 -0
- package/dist/fuzz/prng.js +52 -0
- package/dist/fuzz/prng.js.map +1 -0
- package/dist/fuzz/schema.d.ts +46 -0
- package/dist/fuzz/schema.d.ts.map +1 -0
- package/dist/fuzz/schema.js +84 -0
- package/dist/fuzz/schema.js.map +1 -0
- package/dist/fuzz/types.d.ts +53 -0
- package/dist/fuzz/types.d.ts.map +1 -0
- package/dist/fuzz/types.js +11 -0
- package/dist/fuzz/types.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/report/index.d.ts +25 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +133 -0
- package/dist/report/index.js.map +1 -0
- package/dist/scan/index.d.ts +52 -0
- package/dist/scan/index.d.ts.map +1 -0
- package/dist/scan/index.js +81 -0
- package/dist/scan/index.js.map +1 -0
- package/dist/transport.d.ts +43 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +74 -0
- package/dist/transport.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-spec parsing + transport construction.
|
|
3
|
+
*
|
|
4
|
+
* Per docs/SPEC.md, v0.1 supports three forms:
|
|
5
|
+
*
|
|
6
|
+
* stdio:<command> [args...] — spawn process; stdio transport
|
|
7
|
+
* stdio:./path/to/binary --arg — relative path also accepted
|
|
8
|
+
* http://localhost:3000 — HTTP transport
|
|
9
|
+
*
|
|
10
|
+
* The HTTP transport stub is here for v0.1; the implementation
|
|
11
|
+
* lands in week 2 once we have a real HTTP-transport MCP server to
|
|
12
|
+
* test against. For week 1 the focus is stdio + the official
|
|
13
|
+
* @modelcontextprotocol/server-filesystem.
|
|
14
|
+
*/
|
|
15
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
16
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
17
|
+
/**
|
|
18
|
+
* Parse a server-spec string into structured form.
|
|
19
|
+
*
|
|
20
|
+
* Throws if the spec doesn't match a supported shape — we fail loud
|
|
21
|
+
* here rather than silently degrading to a default, because a
|
|
22
|
+
* mistyped spec produces a confusing connect-failure later.
|
|
23
|
+
*/
|
|
24
|
+
export function parseServerSpec(spec) {
|
|
25
|
+
if (spec.startsWith("stdio:")) {
|
|
26
|
+
const rest = spec.slice("stdio:".length).trim();
|
|
27
|
+
if (rest === "") {
|
|
28
|
+
throw new Error(`parseServerSpec: stdio: prefix requires a command after the colon (got "${spec}")`);
|
|
29
|
+
}
|
|
30
|
+
// Naive shell-splitting: split on whitespace. Good enough for
|
|
31
|
+
// `stdio:npx @modelcontextprotocol/server-filesystem /tmp` and
|
|
32
|
+
// similar. v0.2 may add proper quoting if real specs need it.
|
|
33
|
+
const parts = rest.split(/\s+/).filter((p) => p.length > 0);
|
|
34
|
+
const command = parts[0];
|
|
35
|
+
if (command === undefined) {
|
|
36
|
+
throw new Error(`parseServerSpec: command empty after split (got "${spec}")`);
|
|
37
|
+
}
|
|
38
|
+
return { kind: "stdio", command, args: parts.slice(1) };
|
|
39
|
+
}
|
|
40
|
+
if (spec.startsWith("http://") || spec.startsWith("https://")) {
|
|
41
|
+
return { kind: "http", url: spec };
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`parseServerSpec: unrecognised spec "${spec}" — expected stdio:<cmd> or http(s)://...`);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Open a connected MCP `Client` for the given spec.
|
|
47
|
+
*
|
|
48
|
+
* Caller owns shutdown — pass the result to `closeClient` when
|
|
49
|
+
* finished. We do not auto-close on process exit because some
|
|
50
|
+
* commands (`scan`) hold the client across multiple steps.
|
|
51
|
+
*/
|
|
52
|
+
export async function openClient(spec) {
|
|
53
|
+
const client = new Client({ name: "mcp-recon", version: "0.0.1" }, { capabilities: {} });
|
|
54
|
+
switch (spec.kind) {
|
|
55
|
+
case "stdio": {
|
|
56
|
+
const transport = new StdioClientTransport({
|
|
57
|
+
command: spec.command,
|
|
58
|
+
args: spec.args,
|
|
59
|
+
});
|
|
60
|
+
await client.connect(transport);
|
|
61
|
+
return client;
|
|
62
|
+
}
|
|
63
|
+
case "http": {
|
|
64
|
+
// Stub — v0.1 week 2 will wire this against an HTTP MCP
|
|
65
|
+
// server. The MCP SDK's HTTP transport is the natural target.
|
|
66
|
+
throw new Error(`openClient: http transport not implemented in v0.1 scaffold (got ${spec.url})`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Close a client opened by `openClient`. Safe to call multiple times. */
|
|
71
|
+
export async function closeClient(client) {
|
|
72
|
+
await client.close();
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAOjF;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,2EAA2E,IAAI,IAAI,CACpF,CAAC;QACJ,CAAC;QACD,8DAA8D;QAC9D,+DAA+D;QAC/D,8DAA8D;QAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,oDAAoD,IAAI,IAAI,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IACrC,CAAC;IACD,MAAM,IAAI,KAAK,CACb,uCAAuC,IAAI,2CAA2C,CACvF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAgB;IAC/C,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,EACvC,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;IAEF,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,SAAS,GAAG,IAAI,oBAAoB,CAAC;gBACzC,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB,CAAC,CAAC;YACH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAChC,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,wDAAwD;YACxD,8DAA8D;YAC9D,MAAM,IAAI,KAAK,CACb,oEAAoE,IAAI,CAAC,GAAG,GAAG,CAChF,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAc;IAC9C,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mcp-recon",
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Reverse-engineer MCP server tool surfaces. Enumerate, fuzz, classify, report. CLI + library.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mcp",
|
|
7
|
+
"model-context-protocol",
|
|
8
|
+
"ai-security",
|
|
9
|
+
"agent-security",
|
|
10
|
+
"owasp-llm",
|
|
11
|
+
"mitre-atlas",
|
|
12
|
+
"security",
|
|
13
|
+
"cli"
|
|
14
|
+
],
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"author": "Euan Crosson <euanmcrosson@gmail.com>",
|
|
17
|
+
"homepage": "https://github.com/euanmcrosson-dotcom/mcp-recon#readme",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "https://github.com/euanmcrosson-dotcom/mcp-recon.git",
|
|
21
|
+
"directory": "packages/mcp-recon-cli"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/euanmcrosson-dotcom/mcp-recon/issues"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"main": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"import": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"bin": {
|
|
36
|
+
"mcp-recon": "./dist/bin/recon.js"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE"
|
|
42
|
+
],
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=20.0.0"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"build": "tsc",
|
|
53
|
+
"lint": "biome check src",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"recon": "tsx src/bin/recon.ts",
|
|
56
|
+
"bench": "tsx bench/run.ts",
|
|
57
|
+
"prepublishOnly": "npm run build"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@biomejs/biome": "2.4.14",
|
|
64
|
+
"@types/node": "25.6.0",
|
|
65
|
+
"ajv": "^8.20.0",
|
|
66
|
+
"ajv-formats": "^3.0.1",
|
|
67
|
+
"tinybench": "^2.9.0",
|
|
68
|
+
"tsx": "^4.21.0",
|
|
69
|
+
"typescript": "6.0.3",
|
|
70
|
+
"vitest": "^4.1.5"
|
|
71
|
+
}
|
|
72
|
+
}
|