tare-mcp 0.2.0
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 +21 -0
- package/README.md +668 -0
- package/dist/cli.js +2401 -0
- package/dist/index.js +2199 -0
- package/examples/live-stdio/.mcp.json +8 -0
- package/examples/live-stdio/README.md +28 -0
- package/examples/live-stdio/server.mjs +58 -0
- package/examples/live-streamable-http/.mcp.json +7 -0
- package/examples/live-streamable-http/README.md +40 -0
- package/examples/live-streamable-http/server.mjs +106 -0
- package/examples/scenarios/README.md +44 -0
- package/examples/scenarios/hosted-streamable-http.mcp.json +11 -0
- package/examples/scenarios/local-stdio.mcp.json +8 -0
- package/examples/stdio.mcp.json +11 -0
- package/examples/streamable-http.mcp.json +10 -0
- package/package.json +70 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Live stdio example
|
|
2
|
+
|
|
3
|
+
This is a tiny no-credentials MCP server for smoke-testing `tare-mcp` live inspection.
|
|
4
|
+
|
|
5
|
+
From the repository root:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm install
|
|
9
|
+
pnpm build
|
|
10
|
+
cd examples/live-stdio
|
|
11
|
+
mkdir -p .home
|
|
12
|
+
HOME="$PWD/.home" node ../../dist/cli.js
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The temporary `HOME` keeps the run focused on this example's `.mcp.json` instead of reading your real Claude, Cursor, or VS Code MCP configs.
|
|
16
|
+
|
|
17
|
+
Expected shape:
|
|
18
|
+
|
|
19
|
+
```txt
|
|
20
|
+
Inspecting tare-live-example via stdio...
|
|
21
|
+
|
|
22
|
+
tare-mcp — MCP context weight
|
|
23
|
+
|
|
24
|
+
Config files found: 1
|
|
25
|
+
Servers analyzed: 1
|
|
26
|
+
Inspection mode: live default
|
|
27
|
+
Tools exposed: 2
|
|
28
|
+
```
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
+
|
|
5
|
+
const server = new Server(
|
|
6
|
+
{
|
|
7
|
+
name: "tare-live-example",
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
capabilities: {
|
|
12
|
+
tools: {}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
server.setRequestHandler(ListToolsRequestSchema, () => ({
|
|
18
|
+
tools: [
|
|
19
|
+
{
|
|
20
|
+
name: "echo",
|
|
21
|
+
description: "Echo a short message back to the caller.",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
message: {
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "Message to echo."
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
required: ["message"]
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "summarize_text",
|
|
35
|
+
description: "Summarize a small block of plain text for a quick local MCP smoke test.",
|
|
36
|
+
inputSchema: {
|
|
37
|
+
type: "object",
|
|
38
|
+
properties: {
|
|
39
|
+
text: {
|
|
40
|
+
type: "string",
|
|
41
|
+
description: "Plain text to summarize."
|
|
42
|
+
},
|
|
43
|
+
maxSentences: {
|
|
44
|
+
type: "number",
|
|
45
|
+
description: "Maximum number of sentences to return."
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
required: ["text"]
|
|
49
|
+
},
|
|
50
|
+
annotations: {
|
|
51
|
+
readOnlyHint: true,
|
|
52
|
+
destructiveHint: false
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}));
|
|
57
|
+
|
|
58
|
+
await server.connect(new StdioServerTransport());
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Live Streamable HTTP example
|
|
2
|
+
|
|
3
|
+
This is a tiny no-credentials MCP server for smoke-testing `tare-mcp` live inspection over Streamable HTTP.
|
|
4
|
+
|
|
5
|
+
From the repository root:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm install
|
|
9
|
+
pnpm build
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Terminal 1:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cd examples/live-streamable-http
|
|
16
|
+
node server.mjs
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Terminal 2:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cd examples/live-streamable-http
|
|
23
|
+
mkdir -p .home
|
|
24
|
+
HOME="$PWD/.home" node ../../dist/cli.js
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The temporary `HOME` keeps the run focused on this example's `.mcp.json` instead of reading your real Claude, Cursor, or VS Code MCP configs.
|
|
28
|
+
|
|
29
|
+
Expected shape:
|
|
30
|
+
|
|
31
|
+
```txt
|
|
32
|
+
Inspecting tare-live-http-example via streamable-http...
|
|
33
|
+
|
|
34
|
+
tare-mcp — MCP context weight
|
|
35
|
+
|
|
36
|
+
Config files found: 1
|
|
37
|
+
Servers analyzed: 1
|
|
38
|
+
Inspection mode: live default
|
|
39
|
+
Tools exposed: 2
|
|
40
|
+
```
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
5
|
+
import { ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
6
|
+
|
|
7
|
+
const port = Number(process.env.PORT ?? 33221);
|
|
8
|
+
const transport = new StreamableHTTPServerTransport({
|
|
9
|
+
enableJsonResponse: true,
|
|
10
|
+
sessionIdGenerator: randomUUID
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const mcpServer = new Server(
|
|
14
|
+
{
|
|
15
|
+
name: "tare-live-http-example",
|
|
16
|
+
version: "1.0.0"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
capabilities: {
|
|
20
|
+
tools: {}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
mcpServer.setRequestHandler(ListToolsRequestSchema, () => ({
|
|
26
|
+
tools: [
|
|
27
|
+
{
|
|
28
|
+
name: "search_docs",
|
|
29
|
+
description: "Search local documentation by keyword for a Streamable HTTP MCP smoke test.",
|
|
30
|
+
inputSchema: {
|
|
31
|
+
type: "object",
|
|
32
|
+
properties: {
|
|
33
|
+
query: {
|
|
34
|
+
type: "string",
|
|
35
|
+
description: "Search query."
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
required: ["query"]
|
|
39
|
+
},
|
|
40
|
+
annotations: {
|
|
41
|
+
readOnlyHint: true,
|
|
42
|
+
destructiveHint: false
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "read_doc",
|
|
47
|
+
description: "Read a single documentation page by slug.",
|
|
48
|
+
inputSchema: {
|
|
49
|
+
type: "object",
|
|
50
|
+
properties: {
|
|
51
|
+
slug: {
|
|
52
|
+
type: "string",
|
|
53
|
+
description: "Documentation page slug."
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
required: ["slug"]
|
|
57
|
+
},
|
|
58
|
+
annotations: {
|
|
59
|
+
readOnlyHint: true,
|
|
60
|
+
destructiveHint: false
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}));
|
|
65
|
+
|
|
66
|
+
await mcpServer.connect(transport);
|
|
67
|
+
|
|
68
|
+
async function readJsonBody(request) {
|
|
69
|
+
const chunks = [];
|
|
70
|
+
for await (const chunk of request) {
|
|
71
|
+
chunks.push(chunk);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (chunks.length === 0) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const httpServer = createServer(async (request, response) => {
|
|
82
|
+
if (!request.url?.startsWith("/mcp")) {
|
|
83
|
+
response.writeHead(404).end("Not found");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const body = request.method === "POST" ? await readJsonBody(request) : undefined;
|
|
89
|
+
await transport.handleRequest(request, response, body);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
92
|
+
response.writeHead(500, { "content-type": "text/plain" }).end(message);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
httpServer.listen(port, "127.0.0.1", () => {
|
|
97
|
+
console.error(`tare-live-http-example listening on http://127.0.0.1:${port}/mcp`);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
101
|
+
process.on(signal, () => {
|
|
102
|
+
httpServer.close(() => {
|
|
103
|
+
process.exit(0);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Scenario Examples
|
|
2
|
+
|
|
3
|
+
Copy one of these files into an empty directory as `.mcp.json`, then run `tare-mcp` from that directory.
|
|
4
|
+
|
|
5
|
+
## Hosted Streamable HTTP
|
|
6
|
+
|
|
7
|
+
Use this when you want to inspect a hosted MCP endpoint.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
mkdir -p /tmp/tare-mcp-hosted
|
|
11
|
+
cd /tmp/tare-mcp-hosted
|
|
12
|
+
cp /path/to/tare-mcp/examples/scenarios/hosted-streamable-http.mcp.json .mcp.json
|
|
13
|
+
export LAST9_MCP_TOKEN="..."
|
|
14
|
+
npx tare-mcp --timeout 10000
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This config uses:
|
|
18
|
+
|
|
19
|
+
```txt
|
|
20
|
+
https://mcp.last9.io/mcp
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
If the token is missing or invalid, `tare-mcp` reports a `401 Unauthorized` fallback instead of crashing.
|
|
24
|
+
|
|
25
|
+
## Local stdio
|
|
26
|
+
|
|
27
|
+
Use this when you want to inspect a packaged stdio MCP server.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
mkdir -p /tmp/tare-mcp-stdio
|
|
31
|
+
cd /tmp/tare-mcp-stdio
|
|
32
|
+
cp /path/to/tare-mcp/examples/scenarios/local-stdio.mcp.json .mcp.json
|
|
33
|
+
npx tare-mcp --timeout 10000
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Static-only CI Check
|
|
37
|
+
|
|
38
|
+
Use this when CI should not execute MCP server commands or call hosted MCP URLs.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx tare-mcp --no-exec --json
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Static-only output is intentionally marked insufficient because it cannot see exposed tool schemas.
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tare-mcp",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Local-first CLI for analyzing MCP context weight and tool ambiguity.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"packageManager": "pnpm@10.32.1",
|
|
8
|
+
"bin": {
|
|
9
|
+
"tare-mcp": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/nishantmodak/tare-mcp.git"
|
|
18
|
+
},
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/nishantmodak/tare-mcp/issues"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/nishantmodak/tare-mcp#readme",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"examples",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup",
|
|
37
|
+
"dev": "tsx src/cli.ts",
|
|
38
|
+
"test": "vitest run",
|
|
39
|
+
"lint": "eslint src",
|
|
40
|
+
"format": "prettier --write src"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"mcp",
|
|
44
|
+
"model-context-protocol",
|
|
45
|
+
"cli",
|
|
46
|
+
"tokens",
|
|
47
|
+
"context"
|
|
48
|
+
],
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@modelcontextprotocol/sdk": "latest",
|
|
51
|
+
"commander": "latest",
|
|
52
|
+
"fast-glob": "latest",
|
|
53
|
+
"gpt-tokenizer": "latest",
|
|
54
|
+
"natural": "latest",
|
|
55
|
+
"picocolors": "latest",
|
|
56
|
+
"zod": "latest"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@eslint/js": "latest",
|
|
60
|
+
"@types/natural": "latest",
|
|
61
|
+
"@types/node": "latest",
|
|
62
|
+
"eslint": "latest",
|
|
63
|
+
"prettier": "latest",
|
|
64
|
+
"tsup": "latest",
|
|
65
|
+
"tsx": "latest",
|
|
66
|
+
"typescript": "latest",
|
|
67
|
+
"typescript-eslint": "latest",
|
|
68
|
+
"vitest": "latest"
|
|
69
|
+
}
|
|
70
|
+
}
|