@shuji-bonji/rfcxml-mcp 0.2.0 → 0.4.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.ja.md +10 -6
- package/README.md +6 -0
- package/dist/config.d.ts +26 -26
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +28 -25
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +11 -5
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +15 -7
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +25 -55
- package/dist/index.js.map +1 -1
- package/dist/services/rfc-fetcher.d.ts +11 -11
- package/dist/services/rfc-fetcher.d.ts.map +1 -1
- package/dist/services/rfc-fetcher.js +37 -31
- package/dist/services/rfc-fetcher.js.map +1 -1
- package/dist/services/rfc-text-parser.d.ts.map +1 -1
- package/dist/services/rfc-text-parser.js +4 -3
- package/dist/services/rfc-text-parser.js.map +1 -1
- package/dist/services/rfcxml-parser.d.ts +1 -0
- package/dist/services/rfcxml-parser.d.ts.map +1 -1
- package/dist/services/rfcxml-parser.js +15 -9
- package/dist/services/rfcxml-parser.js.map +1 -1
- package/dist/tools/definitions.d.ts +1 -1
- package/dist/tools/definitions.js +27 -27
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/handlers.d.ts +50 -14
- package/dist/tools/handlers.d.ts.map +1 -1
- package/dist/tools/handlers.js +87 -60
- package/dist/tools/handlers.js.map +1 -1
- package/dist/utils/validation.d.ts +14 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +30 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -111,10 +111,12 @@ RFC 8650 (2019年12月) 以降は公式 RFCXML v3 形式で提供されていま
|
|
|
111
111
|
"rfc": 6455,
|
|
112
112
|
"sections": [...],
|
|
113
113
|
"_source": "text",
|
|
114
|
-
"_sourceNote": "
|
|
114
|
+
"_sourceNote": "Warning: Parsed from text format. Accuracy may be limited."
|
|
115
115
|
}
|
|
116
116
|
```
|
|
117
117
|
|
|
118
|
+
> **Note**: v0.4.0 以降、すべてのメッセージは英語で出力されます(国際化対応)。
|
|
119
|
+
|
|
118
120
|
| `_source` | 説明 |
|
|
119
121
|
|-----------|------|
|
|
120
122
|
| `xml` | RFCXML から解析(高精度) |
|
|
@@ -211,20 +213,22 @@ RFC 8650 (2019年12月) 以降は公式 RFCXML v3 形式で提供されていま
|
|
|
211
213
|
|
|
212
214
|
### `generate_checklist` - 実装チェックリスト生成
|
|
213
215
|
|
|
216
|
+
> **Note**: v0.4.0 以降、チェックリストは英語で出力されます。
|
|
217
|
+
|
|
214
218
|
```markdown
|
|
215
|
-
# RFC 9293
|
|
219
|
+
# RFC 9293 Implementation Checklist
|
|
216
220
|
|
|
217
221
|
**Transmission Control Protocol (TCP)**
|
|
218
222
|
|
|
219
|
-
|
|
223
|
+
Role: client
|
|
220
224
|
|
|
221
|
-
##
|
|
225
|
+
## Mandatory Requirements (MUST / REQUIRED / SHALL)
|
|
222
226
|
|
|
223
227
|
- [ ] A TCP implementation support simultaneous open attempts (MUST-10). (section-3.5)
|
|
224
228
|
- [ ] TCP endpoints implement both sending and receiving the MSS Option (MUST-14). (section-3.7.1)
|
|
225
229
|
- [ ] The RTO be computed according to the algorithm in, including Karn's algorithm (MUST-18). (section-3.8.1)
|
|
226
230
|
|
|
227
|
-
##
|
|
231
|
+
## Optional Requirements (MAY / OPTIONAL)
|
|
228
232
|
|
|
229
233
|
- [ ] Implementers include "keep-alives" in their TCP implementations (MAY-5). (section-3.8.4)
|
|
230
234
|
```
|
|
@@ -242,7 +246,7 @@ RFC 8650 (2019年12月) 以降は公式 RFCXML v3 形式で提供されていま
|
|
|
242
246
|
{ "number": "5", "title": "Data Framing" }
|
|
243
247
|
],
|
|
244
248
|
"_source": "text",
|
|
245
|
-
"_sourceNote": "
|
|
249
|
+
"_sourceNote": "Warning: Parsed from text format. Accuracy may be limited."
|
|
246
250
|
}
|
|
247
251
|
```
|
|
248
252
|
|
package/README.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# RFCXML MCP Server
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@shuji-bonji/rfcxml-mcp)
|
|
4
|
+
[](https://github.com/shuji-bonji/rfcxml-mcp/actions/workflows/ci.yml)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://nodejs.org/)
|
|
7
|
+
[](https://claude.ai/code)
|
|
8
|
+
|
|
3
9
|
A Model Context Protocol (MCP) server for **structured understanding** of RFC documents.
|
|
4
10
|
|
|
5
11
|
## Purpose
|
package/dist/config.d.ts
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Application Configuration
|
|
3
|
+
* Centralized configuration management
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Package information (dynamically loaded from package.json)
|
|
7
7
|
*/
|
|
8
8
|
export declare const PACKAGE_INFO: {
|
|
9
|
-
readonly name:
|
|
10
|
-
readonly version:
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly version: string;
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
|
-
* HTTP
|
|
13
|
+
* HTTP request configuration
|
|
14
14
|
*/
|
|
15
15
|
export declare const HTTP_CONFIG: {
|
|
16
|
-
/** User-Agent
|
|
17
|
-
readonly userAgent:
|
|
18
|
-
/**
|
|
16
|
+
/** User-Agent header */
|
|
17
|
+
readonly userAgent: `${string}/${string}`;
|
|
18
|
+
/** Timeout in milliseconds */
|
|
19
19
|
readonly timeout: 30000;
|
|
20
|
-
/**
|
|
20
|
+
/** Maximum retry attempts */
|
|
21
21
|
readonly maxRetries: 3;
|
|
22
22
|
};
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* Cache configuration
|
|
25
25
|
*/
|
|
26
26
|
export declare const CACHE_CONFIG: {
|
|
27
|
-
/** XML
|
|
27
|
+
/** XML raw data cache (smaller since parsed cache is primary) */
|
|
28
28
|
readonly xml: {
|
|
29
29
|
readonly maxSize: 20;
|
|
30
30
|
readonly name: "XMLCache";
|
|
31
31
|
};
|
|
32
|
-
/**
|
|
32
|
+
/** Text raw data cache */
|
|
33
33
|
readonly text: {
|
|
34
34
|
readonly maxSize: 20;
|
|
35
35
|
readonly name: "TextCache";
|
|
36
36
|
};
|
|
37
|
-
/**
|
|
37
|
+
/** Metadata cache (lightweight, so larger) */
|
|
38
38
|
readonly metadata: {
|
|
39
39
|
readonly maxSize: 100;
|
|
40
40
|
readonly name: "MetadataCache";
|
|
41
41
|
};
|
|
42
|
-
/**
|
|
42
|
+
/** Parsed RFC cache (main cache) */
|
|
43
43
|
readonly parsed: {
|
|
44
44
|
readonly maxSize: 50;
|
|
45
45
|
readonly name: "ParseCache";
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
48
|
/**
|
|
49
|
-
* RFC
|
|
49
|
+
* RFC-related configuration
|
|
50
50
|
*/
|
|
51
51
|
export declare const RFC_CONFIG: {
|
|
52
52
|
/**
|
|
53
|
-
* RFCXML v3
|
|
54
|
-
* RFC 8650 (2019
|
|
53
|
+
* Minimum RFC number where RFCXML v3 is reliably available
|
|
54
|
+
* RFC 8650 (December 2019) and later use official RFCXML v3 format
|
|
55
55
|
*/
|
|
56
56
|
readonly xmlAvailableFrom: 8650;
|
|
57
57
|
};
|
|
58
58
|
/**
|
|
59
|
-
* RFC XML
|
|
60
|
-
*
|
|
59
|
+
* RFC XML source URLs
|
|
60
|
+
* Defined in priority order
|
|
61
61
|
*/
|
|
62
62
|
export declare const RFC_XML_SOURCES: {
|
|
63
|
-
/** RFC Editor
|
|
63
|
+
/** RFC Editor official */
|
|
64
64
|
readonly rfcEditor: (num: number) => string;
|
|
65
65
|
/** IETF Tools */
|
|
66
66
|
readonly ietfTools: (num: number) => string;
|
|
@@ -68,11 +68,11 @@ export declare const RFC_XML_SOURCES: {
|
|
|
68
68
|
readonly datatracker: (num: number) => string;
|
|
69
69
|
};
|
|
70
70
|
/**
|
|
71
|
-
* RFC
|
|
72
|
-
*
|
|
71
|
+
* RFC text source URLs
|
|
72
|
+
* Defined in priority order
|
|
73
73
|
*/
|
|
74
74
|
export declare const RFC_TEXT_SOURCES: {
|
|
75
|
-
/** RFC Editor
|
|
75
|
+
/** RFC Editor official (text) */
|
|
76
76
|
readonly rfcEditor: (num: number) => string;
|
|
77
77
|
/** IETF Tools */
|
|
78
78
|
readonly ietfTools: (num: number) => string;
|
|
@@ -81,11 +81,11 @@ export declare const RFC_TEXT_SOURCES: {
|
|
|
81
81
|
* IETF Datatracker API
|
|
82
82
|
*/
|
|
83
83
|
export declare const DATATRACKER_API: {
|
|
84
|
-
/** RFC
|
|
84
|
+
/** RFC document information */
|
|
85
85
|
readonly document: (num: number) => string;
|
|
86
86
|
};
|
|
87
87
|
/**
|
|
88
|
-
* RFC
|
|
88
|
+
* Check if RFC is likely available in XML format
|
|
89
89
|
*/
|
|
90
90
|
export declare function isRFCXMLLikelyAvailable(rfcNumber: number): boolean;
|
|
91
91
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;GAEG;AACH,eAAO,MAAM,YAAY;;;CAGf,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB,wBAAwB;;IAExB,8BAA8B;;IAE9B,6BAA6B;;CAErB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,YAAY;IACvB,iEAAiE;;;;;IAKjE,0BAA0B;;;;;IAK1B,8CAA8C;;;;;IAK9C,oCAAoC;;;;;CAK5B,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,UAAU;IACrB;;;OAGG;;CAEK,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,eAAe;IAC1B,0BAA0B;8BACT,MAAM;IACvB,iBAAiB;8BACA,MAAM;IACvB,kBAAkB;gCACC,MAAM;CACjB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAC3B,iCAAiC;8BAChB,MAAM;IACvB,iBAAiB;8BACA,MAAM;CACf,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe;IAC1B,+BAA+B;6BACf,MAAM;CACd,CAAC;AAEX;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAElE"}
|
package/dist/config.js
CHANGED
|
@@ -1,66 +1,69 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Application Configuration
|
|
3
|
+
* Centralized configuration management
|
|
4
4
|
*/
|
|
5
|
+
import { createRequire } from 'module';
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const packageJson = require('../package.json');
|
|
5
8
|
/**
|
|
6
|
-
*
|
|
9
|
+
* Package information (dynamically loaded from package.json)
|
|
7
10
|
*/
|
|
8
11
|
export const PACKAGE_INFO = {
|
|
9
|
-
name:
|
|
10
|
-
version:
|
|
12
|
+
name: packageJson.name,
|
|
13
|
+
version: packageJson.version,
|
|
11
14
|
};
|
|
12
15
|
/**
|
|
13
|
-
* HTTP
|
|
16
|
+
* HTTP request configuration
|
|
14
17
|
*/
|
|
15
18
|
export const HTTP_CONFIG = {
|
|
16
|
-
/** User-Agent
|
|
19
|
+
/** User-Agent header */
|
|
17
20
|
userAgent: `${PACKAGE_INFO.name}/${PACKAGE_INFO.version}`,
|
|
18
|
-
/**
|
|
21
|
+
/** Timeout in milliseconds */
|
|
19
22
|
timeout: 30000,
|
|
20
|
-
/**
|
|
23
|
+
/** Maximum retry attempts */
|
|
21
24
|
maxRetries: 3,
|
|
22
25
|
};
|
|
23
26
|
/**
|
|
24
|
-
*
|
|
27
|
+
* Cache configuration
|
|
25
28
|
*/
|
|
26
29
|
export const CACHE_CONFIG = {
|
|
27
|
-
/** XML
|
|
30
|
+
/** XML raw data cache (smaller since parsed cache is primary) */
|
|
28
31
|
xml: {
|
|
29
32
|
maxSize: 20,
|
|
30
33
|
name: 'XMLCache',
|
|
31
34
|
},
|
|
32
|
-
/**
|
|
35
|
+
/** Text raw data cache */
|
|
33
36
|
text: {
|
|
34
37
|
maxSize: 20,
|
|
35
38
|
name: 'TextCache',
|
|
36
39
|
},
|
|
37
|
-
/**
|
|
40
|
+
/** Metadata cache (lightweight, so larger) */
|
|
38
41
|
metadata: {
|
|
39
42
|
maxSize: 100,
|
|
40
43
|
name: 'MetadataCache',
|
|
41
44
|
},
|
|
42
|
-
/**
|
|
45
|
+
/** Parsed RFC cache (main cache) */
|
|
43
46
|
parsed: {
|
|
44
47
|
maxSize: 50,
|
|
45
48
|
name: 'ParseCache',
|
|
46
49
|
},
|
|
47
50
|
};
|
|
48
51
|
/**
|
|
49
|
-
* RFC
|
|
52
|
+
* RFC-related configuration
|
|
50
53
|
*/
|
|
51
54
|
export const RFC_CONFIG = {
|
|
52
55
|
/**
|
|
53
|
-
* RFCXML v3
|
|
54
|
-
* RFC 8650 (2019
|
|
56
|
+
* Minimum RFC number where RFCXML v3 is reliably available
|
|
57
|
+
* RFC 8650 (December 2019) and later use official RFCXML v3 format
|
|
55
58
|
*/
|
|
56
59
|
xmlAvailableFrom: 8650,
|
|
57
60
|
};
|
|
58
61
|
/**
|
|
59
|
-
* RFC XML
|
|
60
|
-
*
|
|
62
|
+
* RFC XML source URLs
|
|
63
|
+
* Defined in priority order
|
|
61
64
|
*/
|
|
62
65
|
export const RFC_XML_SOURCES = {
|
|
63
|
-
/** RFC Editor
|
|
66
|
+
/** RFC Editor official */
|
|
64
67
|
rfcEditor: (num) => `https://www.rfc-editor.org/rfc/rfc${num}.xml`,
|
|
65
68
|
/** IETF Tools */
|
|
66
69
|
ietfTools: (num) => `https://xml2rfc.ietf.org/public/rfc/rfc${num}.xml`,
|
|
@@ -68,11 +71,11 @@ export const RFC_XML_SOURCES = {
|
|
|
68
71
|
datatracker: (num) => `https://datatracker.ietf.org/doc/rfc${num}/xml/`,
|
|
69
72
|
};
|
|
70
73
|
/**
|
|
71
|
-
* RFC
|
|
72
|
-
*
|
|
74
|
+
* RFC text source URLs
|
|
75
|
+
* Defined in priority order
|
|
73
76
|
*/
|
|
74
77
|
export const RFC_TEXT_SOURCES = {
|
|
75
|
-
/** RFC Editor
|
|
78
|
+
/** RFC Editor official (text) */
|
|
76
79
|
rfcEditor: (num) => `https://www.rfc-editor.org/rfc/rfc${num}.txt`,
|
|
77
80
|
/** IETF Tools */
|
|
78
81
|
ietfTools: (num) => `https://tools.ietf.org/rfc/rfc${num}.txt`,
|
|
@@ -81,11 +84,11 @@ export const RFC_TEXT_SOURCES = {
|
|
|
81
84
|
* IETF Datatracker API
|
|
82
85
|
*/
|
|
83
86
|
export const DATATRACKER_API = {
|
|
84
|
-
/** RFC
|
|
87
|
+
/** RFC document information */
|
|
85
88
|
document: (num) => `https://datatracker.ietf.org/api/v1/doc/document/rfc${num}/`,
|
|
86
89
|
};
|
|
87
90
|
/**
|
|
88
|
-
* RFC
|
|
91
|
+
* Check if RFC is likely available in XML format
|
|
89
92
|
*/
|
|
90
93
|
export function isRFCXMLLikelyAvailable(rfcNumber) {
|
|
91
94
|
return rfcNumber >= RFC_CONFIG.xmlAvailableFrom;
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAsC,CAAC;AAEpF;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,WAAW,CAAC,IAAI;IACtB,OAAO,EAAE,WAAW,CAAC,OAAO;CACpB,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,wBAAwB;IACxB,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,IAAI,YAAY,CAAC,OAAO,EAAE;IACzD,8BAA8B;IAC9B,OAAO,EAAE,KAAK;IACd,6BAA6B;IAC7B,UAAU,EAAE,CAAC;CACL,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,iEAAiE;IACjE,GAAG,EAAE;QACH,OAAO,EAAE,EAAE;QACX,IAAI,EAAE,UAAU;KACjB;IACD,0BAA0B;IAC1B,IAAI,EAAE;QACJ,OAAO,EAAE,EAAE;QACX,IAAI,EAAE,WAAW;KAClB;IACD,8CAA8C;IAC9C,QAAQ,EAAE;QACR,OAAO,EAAE,GAAG;QACZ,IAAI,EAAE,eAAe;KACtB;IACD,oCAAoC;IACpC,MAAM,EAAE;QACN,OAAO,EAAE,EAAE;QACX,IAAI,EAAE,YAAY;KACnB;CACO,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB;;;OAGG;IACH,gBAAgB,EAAE,IAAI;CACd,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,0BAA0B;IAC1B,SAAS,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,qCAAqC,GAAG,MAAM;IAC1E,iBAAiB;IACjB,SAAS,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,0CAA0C,GAAG,MAAM;IAC/E,kBAAkB;IAClB,WAAW,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,uCAAuC,GAAG,OAAO;CACvE,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,iCAAiC;IACjC,SAAS,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,qCAAqC,GAAG,MAAM;IAC1E,iBAAiB;IACjB,SAAS,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,iCAAiC,GAAG,MAAM;CAC9D,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,+BAA+B;IAC/B,QAAQ,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,uDAAuD,GAAG,GAAG;CAChF,CAAC;AAEX;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,OAAO,SAAS,IAAI,UAAU,CAAC,gBAAgB,CAAC;AAClD,CAAC"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* BCP 14 / RFC 2119
|
|
2
|
+
* Common Constants
|
|
3
|
+
* BCP 14 / RFC 2119 keywords and patterns
|
|
4
4
|
*/
|
|
5
5
|
import type { RequirementLevel } from './types/index.js';
|
|
6
6
|
/**
|
|
7
|
-
* BCP 14 / RFC 2119
|
|
8
|
-
*
|
|
7
|
+
* BCP 14 / RFC 2119 keywords
|
|
8
|
+
* Ordered by length (longer first to match "MUST NOT" before "MUST")
|
|
9
9
|
*/
|
|
10
10
|
export declare const REQUIREMENT_KEYWORDS: RequirementLevel[];
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Create a new requirement regex instance
|
|
13
|
+
* Safe for use in loops with exec() - avoids lastIndex state issues
|
|
14
|
+
*/
|
|
15
|
+
export declare function createRequirementRegex(): RegExp;
|
|
16
|
+
/**
|
|
17
|
+
* Keyword regex (matches longest first)
|
|
18
|
+
* Note: When using with exec() in loops, prefer createRequirementRegex() to avoid lastIndex issues
|
|
13
19
|
*/
|
|
14
20
|
export declare const REQUIREMENT_REGEX: RegExp;
|
|
15
21
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,gBAAgB,EAYlD,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,gBAAgB,EAYlD,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAA2B,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* BCP 14 / RFC 2119
|
|
2
|
+
* Common Constants
|
|
3
|
+
* BCP 14 / RFC 2119 keywords and patterns
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
|
-
* BCP 14 / RFC 2119
|
|
7
|
-
*
|
|
6
|
+
* BCP 14 / RFC 2119 keywords
|
|
7
|
+
* Ordered by length (longer first to match "MUST NOT" before "MUST")
|
|
8
8
|
*/
|
|
9
9
|
export const REQUIREMENT_KEYWORDS = [
|
|
10
10
|
'MUST NOT',
|
|
@@ -20,10 +20,18 @@ export const REQUIREMENT_KEYWORDS = [
|
|
|
20
20
|
'OPTIONAL',
|
|
21
21
|
];
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Create a new requirement regex instance
|
|
24
|
+
* Safe for use in loops with exec() - avoids lastIndex state issues
|
|
24
25
|
*/
|
|
25
|
-
export
|
|
26
|
-
|
|
26
|
+
export function createRequirementRegex() {
|
|
27
|
+
return new RegExp(`\\b(${REQUIREMENT_KEYWORDS.join('|')})\\b`, 'g');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Keyword regex (matches longest first)
|
|
31
|
+
* Note: When using with exec() in loops, prefer createRequirementRegex() to avoid lastIndex issues
|
|
32
|
+
*/
|
|
33
|
+
export const REQUIREMENT_REGEX = createRequirementRegex();
|
|
34
|
+
// RFC-related configuration is centralized in config.ts
|
|
27
35
|
// - RFC_CONFIG.xmlAvailableFrom
|
|
28
36
|
// - isRFCXMLLikelyAvailable()
|
|
29
37
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAuB;IACtD,UAAU;IACV,MAAM;IACN,UAAU;IACV,WAAW;IACX,OAAO;IACP,YAAY;IACZ,QAAQ;IACR,aAAa;IACb,iBAAiB;IACjB,KAAK;IACL,UAAU;CACX,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAuB;IACtD,UAAU;IACV,MAAM;IACN,UAAU;IACV,WAAW;IACX,OAAO;IACP,YAAY;IACZ,QAAQ;IACR,aAAa;IACb,iBAAiB;IACjB,KAAK;IACL,UAAU;CACX,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,MAAM,CAAC,OAAO,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,sBAAsB,EAAE,CAAC;AAE1D,wDAAwD;AACxD,gCAAgC;AAChC,8BAA8B"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,93 +1,63 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* RFCXML MCP Server
|
|
4
|
-
*
|
|
4
|
+
* MCP server for structural understanding of RFC documents
|
|
5
5
|
*/
|
|
6
6
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
7
7
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
8
|
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
9
9
|
import { tools } from './tools/definitions.js';
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import { toolHandlers } from './tools/handlers.js';
|
|
11
|
+
import { PACKAGE_INFO } from './config.js';
|
|
12
|
+
// Server instance
|
|
12
13
|
const server = new Server({
|
|
13
|
-
name:
|
|
14
|
-
version:
|
|
14
|
+
name: PACKAGE_INFO.name,
|
|
15
|
+
version: PACKAGE_INFO.version,
|
|
15
16
|
}, {
|
|
16
17
|
capabilities: {
|
|
17
18
|
tools: {},
|
|
18
19
|
resources: {},
|
|
19
20
|
},
|
|
20
21
|
});
|
|
21
|
-
//
|
|
22
|
+
// List tools
|
|
22
23
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
23
24
|
return { tools };
|
|
24
25
|
});
|
|
25
|
-
//
|
|
26
|
+
// Execute tool
|
|
26
27
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
27
28
|
const { name, arguments: args } = request.params;
|
|
28
29
|
try {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
result = await handleGetRFCStructure(args);
|
|
33
|
-
break;
|
|
34
|
-
case 'get_requirements':
|
|
35
|
-
result = await handleGetRequirements(args);
|
|
36
|
-
break;
|
|
37
|
-
case 'get_definitions':
|
|
38
|
-
result = await handleGetDefinitions(args);
|
|
39
|
-
break;
|
|
40
|
-
case 'get_rfc_dependencies':
|
|
41
|
-
result = await handleGetDependencies(args);
|
|
42
|
-
break;
|
|
43
|
-
case 'get_related_sections':
|
|
44
|
-
result = await handleGetRelatedSections(args);
|
|
45
|
-
break;
|
|
46
|
-
case 'generate_checklist':
|
|
47
|
-
result = await handleGenerateChecklist(args);
|
|
48
|
-
break;
|
|
49
|
-
case 'validate_statement':
|
|
50
|
-
result = await handleValidateStatement(args);
|
|
51
|
-
break;
|
|
52
|
-
default:
|
|
53
|
-
throw new Error(`Unknown tool: ${name}`);
|
|
30
|
+
const handler = toolHandlers[name];
|
|
31
|
+
if (!handler) {
|
|
32
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
54
33
|
}
|
|
34
|
+
const result = await handler(args);
|
|
55
35
|
return {
|
|
56
|
-
content: [
|
|
57
|
-
{
|
|
58
|
-
type: 'text',
|
|
59
|
-
text: JSON.stringify(result, null, 2),
|
|
60
|
-
},
|
|
61
|
-
],
|
|
36
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
62
37
|
};
|
|
63
38
|
}
|
|
64
39
|
catch (error) {
|
|
65
40
|
const message = error instanceof Error ? error.message : String(error);
|
|
66
41
|
return {
|
|
67
|
-
content: [
|
|
68
|
-
{
|
|
69
|
-
type: 'text',
|
|
70
|
-
text: JSON.stringify({ error: message }, null, 2),
|
|
71
|
-
},
|
|
72
|
-
],
|
|
42
|
+
content: [{ type: 'text', text: JSON.stringify({ error: message }, null, 2) }],
|
|
73
43
|
isError: true,
|
|
74
44
|
};
|
|
75
45
|
}
|
|
76
46
|
});
|
|
77
|
-
//
|
|
47
|
+
// List resources (RFC schema)
|
|
78
48
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
79
49
|
return {
|
|
80
50
|
resources: [
|
|
81
51
|
{
|
|
82
52
|
uri: 'rfcxml://schema',
|
|
83
53
|
name: 'RFCXML Schema Information',
|
|
84
|
-
description: 'RFCXML v3
|
|
54
|
+
description: 'RFCXML v3 structure and schema information',
|
|
85
55
|
mimeType: 'application/json',
|
|
86
56
|
},
|
|
87
57
|
],
|
|
88
58
|
};
|
|
89
59
|
});
|
|
90
|
-
//
|
|
60
|
+
// Read resource
|
|
91
61
|
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
92
62
|
const { uri } = request.params;
|
|
93
63
|
if (uri === 'rfcxml://schema') {
|
|
@@ -101,13 +71,13 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
101
71
|
spec: 'RFC 7991 (superseded by rfc7991bis)',
|
|
102
72
|
documentation: 'https://authors.ietf.org/rfcxml-vocabulary',
|
|
103
73
|
keyElements: {
|
|
104
|
-
bcp14: 'RFC 2119
|
|
105
|
-
xref: '
|
|
106
|
-
reference: '
|
|
107
|
-
section: '
|
|
108
|
-
t: '
|
|
109
|
-
dl: '
|
|
110
|
-
sourcecode: '
|
|
74
|
+
bcp14: 'Markup for RFC 2119 keywords (MUST, SHOULD, MAY, etc.)',
|
|
75
|
+
xref: 'Internal and external references',
|
|
76
|
+
reference: 'Bibliography references',
|
|
77
|
+
section: 'Section structure',
|
|
78
|
+
t: 'Text paragraph',
|
|
79
|
+
dl: 'Definition list',
|
|
80
|
+
sourcecode: 'Source code',
|
|
111
81
|
},
|
|
112
82
|
}, null, 2),
|
|
113
83
|
},
|
|
@@ -116,7 +86,7 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
|
116
86
|
}
|
|
117
87
|
throw new Error(`Unknown resource: ${uri}`);
|
|
118
88
|
});
|
|
119
|
-
//
|
|
89
|
+
// Start server
|
|
120
90
|
async function main() {
|
|
121
91
|
const transport = new StdioServerTransport();
|
|
122
92
|
await server.connect(transport);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* RFC
|
|
3
|
-
* RFCXML
|
|
2
|
+
* RFC Fetcher Service
|
|
3
|
+
* RFCXML source fetching and cache management
|
|
4
4
|
*/
|
|
5
5
|
import type { RFCMetadata } from '../types/index.js';
|
|
6
6
|
/**
|
|
7
|
-
* RFCXML
|
|
8
|
-
*
|
|
7
|
+
* Fetch RFCXML (parallel fetch)
|
|
8
|
+
* Sends concurrent requests to multiple sources and returns the first successful response
|
|
9
9
|
*/
|
|
10
10
|
export declare function fetchRFCXML(rfcNumber: number): Promise<string>;
|
|
11
11
|
/**
|
|
12
|
-
* RFC
|
|
12
|
+
* Fetch RFC metadata (IETF Datatracker API)
|
|
13
13
|
*/
|
|
14
14
|
export declare function fetchRFCMetadata(rfcNumber: number): Promise<RFCMetadata>;
|
|
15
15
|
/**
|
|
16
|
-
* RFC
|
|
17
|
-
*
|
|
16
|
+
* Fetch RFC text (parallel fetch)
|
|
17
|
+
* Sends concurrent requests to multiple sources and returns the first successful response
|
|
18
18
|
*/
|
|
19
19
|
export declare function fetchRFCText(rfcNumber: number): Promise<string>;
|
|
20
20
|
/**
|
|
21
|
-
* RFC
|
|
22
|
-
*
|
|
21
|
+
* Check if RFC is available in XML format
|
|
22
|
+
* Note: RFC 8650 (December 2019) and later use official RFCXML v3
|
|
23
23
|
*/
|
|
24
24
|
export declare function isRFCXMLAvailable(rfcNumber: number): boolean;
|
|
25
25
|
/**
|
|
26
|
-
* RFC XML
|
|
26
|
+
* RFC XML fetch error
|
|
27
27
|
*/
|
|
28
28
|
export declare class RFCXMLNotAvailableError extends Error {
|
|
29
29
|
readonly rfcNumber: number;
|
|
@@ -32,7 +32,7 @@ export declare class RFCXMLNotAvailableError extends Error {
|
|
|
32
32
|
constructor(rfcNumber: number, originalErrors?: string[]);
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
35
|
+
* Clear all caches
|
|
36
36
|
*/
|
|
37
37
|
export declare function clearCache(): void;
|
|
38
38
|
//# sourceMappingURL=rfc-fetcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rfc-fetcher.d.ts","sourceRoot":"","sources":["../../src/services/rfc-fetcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAiBrD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BpE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"rfc-fetcher.d.ts","sourceRoot":"","sources":["../../src/services/rfc-fetcher.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAiBrD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BpE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAyD9E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BrE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,SAAgB,QAAQ,EAAE,OAAO,CAAC;IAClC,SAAgB,UAAU,EAAE,MAAM,CAAC;gBAEvB,SAAS,EAAE,MAAM,EAAE,cAAc,GAAE,MAAM,EAAO;CAoB7D;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAIjC"}
|