mcp-lint 0.6.2 → 0.8.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/README.md +59 -3
- package/dist/cli/commands/check.js +160 -32
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/init.js +1 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/snapshot.d.ts +2 -0
- package/dist/cli/commands/snapshot.js +56 -0
- package/dist/cli/commands/snapshot.js.map +1 -0
- package/dist/discover/files.d.ts +3 -0
- package/dist/discover/files.js +35 -0
- package/dist/discover/files.js.map +1 -0
- package/dist/discover/format.d.ts +6 -0
- package/dist/discover/format.js +20 -0
- package/dist/discover/format.js.map +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/installed/config.d.ts +34 -0
- package/dist/installed/config.js +130 -0
- package/dist/installed/config.js.map +1 -0
- package/dist/installed/format.d.ts +2 -0
- package/dist/installed/format.js +72 -0
- package/dist/installed/format.js.map +1 -0
- package/dist/installed/lint.d.ts +19 -0
- package/dist/installed/lint.js +49 -0
- package/dist/installed/lint.js.map +1 -0
- package/dist/loaders/index.d.ts +1 -0
- package/dist/loaders/index.js +1 -0
- package/dist/loaders/index.js.map +1 -1
- package/dist/loaders/map-tools.d.ts +16 -0
- package/dist/loaders/map-tools.js +33 -0
- package/dist/loaders/map-tools.js.map +1 -0
- package/dist/loaders/remote-loader.d.ts +2 -0
- package/dist/loaders/remote-loader.js +37 -0
- package/dist/loaders/remote-loader.js.map +1 -0
- package/dist/loaders/sse-loader.d.ts +1 -1
- package/dist/loaders/sse-loader.js +3 -17
- package/dist/loaders/sse-loader.js.map +1 -1
- package/dist/loaders/stdio-loader.d.ts +8 -1
- package/dist/loaders/stdio-loader.js +58 -12
- package/dist/loaders/stdio-loader.js.map +1 -1
- package/dist/mcp-server.js +1 -1
- package/dist/recover/probe.js +1 -1
- package/dist/rules/index.js +2 -0
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/tool-name.d.ts +2 -0
- package/dist/rules/tool-name.js +44 -0
- package/dist/rules/tool-name.js.map +1 -0
- package/dist/snapshot/serialize.d.ts +2 -0
- package/dist/snapshot/serialize.js +17 -0
- package/dist/snapshot/serialize.js.map +1 -0
- package/examples/github-action.yml +1 -1
- package/examples/names/unsafe.json +22 -0
- package/package.json +7 -3
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const CLIENTS = [
|
|
2
|
+
'claude', 'cursor', 'gemini', 'vscode', 'windsurf', 'cline', 'openai', 'continue',
|
|
3
|
+
];
|
|
4
|
+
// OpenAI and Azure: ^[A-Za-z0-9_-]{1,64}$
|
|
5
|
+
// Gemini also requires the first character to be a letter or underscore.
|
|
6
|
+
const SAFE_NAME = /^[A-Za-z0-9_-]{1,64}$/;
|
|
7
|
+
const LEADING_DIGIT = /^[0-9]/;
|
|
8
|
+
export const toolNameClientSafe = {
|
|
9
|
+
id: 'tool-name/client-safe',
|
|
10
|
+
severity: 'error',
|
|
11
|
+
description: 'Tool names must be 1–64 characters of letters, digits, underscores, or hyphens, and should not start with a digit.',
|
|
12
|
+
clients: CLIENTS,
|
|
13
|
+
docs: {
|
|
14
|
+
why: 'OpenAI and Azure reject a tool name outside ^[A-Za-z0-9_-]{1,64}$. A space, slash, or dot makes the tool disappear. Gemini also refuses a name that starts with a digit.',
|
|
15
|
+
badExample: { name: 'search files' },
|
|
16
|
+
goodExample: { name: 'search_files' },
|
|
17
|
+
fixNote: 'Rename the tool. Use letters, digits, underscores, or hyphens, start with a letter or underscore, and stay within 64 characters.',
|
|
18
|
+
},
|
|
19
|
+
check(tool, _context) {
|
|
20
|
+
const name = tool.name ?? '';
|
|
21
|
+
if (!SAFE_NAME.test(name)) {
|
|
22
|
+
return [{
|
|
23
|
+
ruleId: 'tool-name/client-safe',
|
|
24
|
+
severity: 'error',
|
|
25
|
+
message: `Tool name "${name}" is not safe across clients. Use 1–64 characters: letters, digits, underscore, or hyphen.`,
|
|
26
|
+
toolName: name || '(unnamed)',
|
|
27
|
+
path: 'name',
|
|
28
|
+
clients: ['claude', 'openai', 'gemini'],
|
|
29
|
+
}];
|
|
30
|
+
}
|
|
31
|
+
if (LEADING_DIGIT.test(name)) {
|
|
32
|
+
return [{
|
|
33
|
+
ruleId: 'tool-name/client-safe',
|
|
34
|
+
severity: 'warning',
|
|
35
|
+
message: `Tool name "${name}" starts with a digit. Gemini requires a letter or an underscore first.`,
|
|
36
|
+
toolName: name,
|
|
37
|
+
path: 'name',
|
|
38
|
+
clients: ['gemini'],
|
|
39
|
+
}];
|
|
40
|
+
}
|
|
41
|
+
return [];
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=tool-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-name.js","sourceRoot":"","sources":["../../src/rules/tool-name.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,GAAe;IAC1B,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU;CAClF,CAAC;AAEF,0CAA0C;AAC1C,yEAAyE;AACzE,MAAM,SAAS,GAAG,uBAAuB,CAAC;AAC1C,MAAM,aAAa,GAAG,QAAQ,CAAC;AAE/B,MAAM,CAAC,MAAM,kBAAkB,GAAS;IACtC,EAAE,EAAE,uBAAuB;IAC3B,QAAQ,EAAE,OAAO;IACjB,WAAW,EAAE,oHAAoH;IACjI,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE;QACJ,GAAG,EAAE,0KAA0K;QAC/K,UAAU,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;QACpC,WAAW,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;QACrC,OAAO,EAAE,kIAAkI;KAC5I;IAED,KAAK,CAAC,IAAa,EAAE,QAAqB;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC;oBACN,MAAM,EAAE,uBAAuB;oBAC/B,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,cAAc,IAAI,4FAA4F;oBACvH,QAAQ,EAAE,IAAI,IAAI,WAAW;oBAC7B,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;iBACxC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC;oBACN,MAAM,EAAE,uBAAuB;oBAC/B,QAAQ,EAAE,SAAS;oBACnB,OAAO,EAAE,cAAc,IAAI,yEAAyE;oBACpG,QAAQ,EAAE,IAAI;oBACd,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,CAAC,QAAQ,CAAC;iBACpB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function serializeTools(tools) {
|
|
2
|
+
const sorted = [...tools].sort((left, right) => left.name.localeCompare(right.name));
|
|
3
|
+
const shaped = sorted.map((tool) => {
|
|
4
|
+
const record = { name: tool.name };
|
|
5
|
+
if (tool.title)
|
|
6
|
+
record.title = tool.title;
|
|
7
|
+
if (tool.description)
|
|
8
|
+
record.description = tool.description;
|
|
9
|
+
record.inputSchema = tool.inputSchema ?? {};
|
|
10
|
+
if (tool.annotations && Object.keys(tool.annotations).length > 0) {
|
|
11
|
+
record.annotations = tool.annotations;
|
|
12
|
+
}
|
|
13
|
+
return record;
|
|
14
|
+
});
|
|
15
|
+
return `${JSON.stringify(shaped, null, 2)}\n`;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=serialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../src/snapshot/serialize.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,cAAc,CAAC,KAAgB;IAC7C,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACjC,MAAM,MAAM,GAA4B,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5D,IAAI,IAAI,CAAC,KAAK;YAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAC1C,IAAI,IAAI,CAAC,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QAC5D,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;QAC5C,IAAI,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACxC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"name": "search files",
|
|
4
|
+
"description": "Search the workspace.",
|
|
5
|
+
"inputSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"q": { "type": "string", "description": "Text to find" }
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "repo/read",
|
|
14
|
+
"description": "Read one file.",
|
|
15
|
+
"inputSchema": { "type": "object", "properties": {} }
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "9tools",
|
|
19
|
+
"description": "List tools.",
|
|
20
|
+
"inputSchema": { "type": "object", "properties": {} }
|
|
21
|
+
}
|
|
22
|
+
]
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-lint",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"mcpName": "io.github.robert19001-cmyk/mcp-lint",
|
|
5
|
-
"description": "Lint MCP
|
|
5
|
+
"description": "Lint MCP tool schemas before they break Claude, Cursor, Gemini, or OpenAI. Run npx mcp-lint.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -62,7 +62,11 @@
|
|
|
62
62
|
"recover",
|
|
63
63
|
"agent-safety",
|
|
64
64
|
"policy",
|
|
65
|
-
"guardrails"
|
|
65
|
+
"guardrails",
|
|
66
|
+
"claude",
|
|
67
|
+
"cursor",
|
|
68
|
+
"openai",
|
|
69
|
+
"gemini"
|
|
66
70
|
],
|
|
67
71
|
"license": "MIT",
|
|
68
72
|
"engines": {
|