@shuji-bonji/rfcxml-mcp 0.1.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 +19 -0
- package/README.md +190 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +129 -0
- package/dist/index.js.map +1 -0
- package/dist/services/rfc-fetcher.d.ts +36 -0
- package/dist/services/rfc-fetcher.d.ts.map +1 -0
- package/dist/services/rfc-fetcher.js +220 -0
- package/dist/services/rfc-fetcher.js.map +1 -0
- package/dist/services/rfc-text-parser.d.ts +18 -0
- package/dist/services/rfc-text-parser.d.ts.map +1 -0
- package/dist/services/rfc-text-parser.js +257 -0
- package/dist/services/rfc-text-parser.js.map +1 -0
- package/dist/services/rfcxml-parser.d.ts +30 -0
- package/dist/services/rfcxml-parser.d.ts.map +1 -0
- package/dist/services/rfcxml-parser.js +430 -0
- package/dist/services/rfcxml-parser.js.map +1 -0
- package/dist/tools/definitions.d.ts +6 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +167 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/handlers.d.ts +113 -0
- package/dist/tools/handlers.d.ts.map +1 -0
- package/dist/tools/handlers.js +353 -0
- package/dist/tools/handlers.js.map +1 -0
- package/dist/types/index.d.ts +159 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2025 shuji-bonji
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# RFCXML MCP Server
|
|
2
|
+
|
|
3
|
+
RFC 文書を **構造的に理解** するための MCP サーバー。
|
|
4
|
+
|
|
5
|
+
## 目的
|
|
6
|
+
|
|
7
|
+
既存の RFC MCP サーバー(テキストベース)と異なり、RFCXML の意味構造を活用して:
|
|
8
|
+
|
|
9
|
+
- **規範性要件(MUST/SHOULD/MAY)** の抽出・構造化
|
|
10
|
+
- **RFC 間依存関係グラフ** の構築
|
|
11
|
+
- **定義語のスコープ管理**
|
|
12
|
+
- **実装チェックリストの自動生成**
|
|
13
|
+
|
|
14
|
+
を可能にする。
|
|
15
|
+
|
|
16
|
+
## レイヤー構造
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
┌─────────────────────────┐
|
|
20
|
+
│ Markdown / PDF │ 表示・共有
|
|
21
|
+
├─────────────────────────┤
|
|
22
|
+
│ 翻訳 │ 説明・検証・普及
|
|
23
|
+
├─────────────────────────┤
|
|
24
|
+
│ RFCXML MCP │ AI と人の共通理解基盤
|
|
25
|
+
├─────────────────────────┤
|
|
26
|
+
│ RFCXML │ 唯一の真実(Single Source of Truth)
|
|
27
|
+
└─────────────────────────┘
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 既存 MCP との違い
|
|
31
|
+
|
|
32
|
+
| 機能 | 既存 mcp-rfc | RFCXML MCP |
|
|
33
|
+
|------|-------------|------------|
|
|
34
|
+
| RFC テキスト取得 | ✅ | ✅ |
|
|
35
|
+
| セクション抽出 | ✅ (テキストベース) | ✅ (構造ベース) |
|
|
36
|
+
| MUST/SHOULD/MAY 抽出 | ❌ | ✅ |
|
|
37
|
+
| 条件・例外の構造化 | ❌ | ✅ |
|
|
38
|
+
| RFC 間依存グラフ | ❌ | ✅ |
|
|
39
|
+
| 定義スコープ管理 | ❌ | ✅ |
|
|
40
|
+
| 実装チェックリスト | ❌ | ✅ |
|
|
41
|
+
|
|
42
|
+
## インストール
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install @shuji-bonji/rfcxml-mcp
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## MCP 設定
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"mcpServers": {
|
|
53
|
+
"rfcxml": {
|
|
54
|
+
"command": "npx",
|
|
55
|
+
"args": ["-y", "@shuji-bonji/rfcxml-mcp"]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 利用可能なツール
|
|
62
|
+
|
|
63
|
+
### Phase 1: 基本構造
|
|
64
|
+
|
|
65
|
+
- `get_rfc_structure` - セクション階層とメタデータ取得
|
|
66
|
+
- `get_requirements` - 規範性要件(MUST/SHOULD/MAY)の構造化抽出
|
|
67
|
+
- `get_definitions` - 用語定義とスコープ
|
|
68
|
+
|
|
69
|
+
### Phase 2: 関係性
|
|
70
|
+
|
|
71
|
+
- `get_rfc_dependencies` - 参照 RFC(normative/informative)
|
|
72
|
+
- `get_related_sections` - 関連セクション(同一 RFC 内)
|
|
73
|
+
|
|
74
|
+
### Phase 3: 検証支援
|
|
75
|
+
|
|
76
|
+
- `validate_statement` - 主張が RFC に準拠しているか検証
|
|
77
|
+
- `generate_checklist` - 実装チェックリスト生成
|
|
78
|
+
|
|
79
|
+
## 古い RFC のサポート
|
|
80
|
+
|
|
81
|
+
RFC 8650 (2019年12月) 以降は公式 RFCXML v3 形式で提供されていますが、それ以前の RFC は XML が利用できない場合があります。
|
|
82
|
+
|
|
83
|
+
このサーバーは **自動フォールバック機能** を備えており、XML が取得できない場合はテキスト形式から解析を行います。
|
|
84
|
+
|
|
85
|
+
### ソース情報
|
|
86
|
+
|
|
87
|
+
すべてのレスポンスには解析ソース情報が含まれます:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"rfc": 6455,
|
|
92
|
+
"sections": [...],
|
|
93
|
+
"_source": "text",
|
|
94
|
+
"_sourceNote": "⚠️ テキストからの解析結果です。精度が低い可能性があります。"
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
| `_source` | 説明 |
|
|
99
|
+
|-----------|------|
|
|
100
|
+
| `xml` | RFCXML から解析(高精度) |
|
|
101
|
+
| `text` | テキストから解析(中精度) |
|
|
102
|
+
|
|
103
|
+
### 対応状況
|
|
104
|
+
|
|
105
|
+
| RFC | 形式 | 備考 |
|
|
106
|
+
|-----|------|------|
|
|
107
|
+
| RFC 8650 以降 | XML | RFCXML v3 公式対応 |
|
|
108
|
+
| RFC 8650 未満 | テキスト | 自動フォールバック |
|
|
109
|
+
|
|
110
|
+
## 使用例
|
|
111
|
+
|
|
112
|
+
### 規範性要件の抽出
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// ツール呼び出し
|
|
116
|
+
{
|
|
117
|
+
"tool": "get_requirements",
|
|
118
|
+
"arguments": {
|
|
119
|
+
"rfc": 6455,
|
|
120
|
+
"section": "5.5.1"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 結果
|
|
125
|
+
{
|
|
126
|
+
"section": "5.5.1",
|
|
127
|
+
"title": "Close",
|
|
128
|
+
"requirements": [
|
|
129
|
+
{
|
|
130
|
+
"id": "R-5.5.1-1",
|
|
131
|
+
"level": "MUST",
|
|
132
|
+
"text": "endpoint MUST send a Close frame",
|
|
133
|
+
"subject": "endpoint",
|
|
134
|
+
"action": "send Close frame",
|
|
135
|
+
"condition": "when closing connection",
|
|
136
|
+
"fullContext": "After sending a control frame indicating..."
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 実装チェックリスト生成
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// ツール呼び出し
|
|
146
|
+
{
|
|
147
|
+
"tool": "generate_checklist",
|
|
148
|
+
"arguments": {
|
|
149
|
+
"rfc": 6455,
|
|
150
|
+
"role": "client"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// 結果(Markdown)
|
|
155
|
+
## RFC 6455 WebSocket Client 実装チェックリスト
|
|
156
|
+
|
|
157
|
+
### 必須要件 (MUST)
|
|
158
|
+
- [ ] Opening Handshake で Sec-WebSocket-Key を含める (Section 4.1)
|
|
159
|
+
- [ ] Close フレーム受信後、TCP 接続を閉じる (Section 5.5.1)
|
|
160
|
+
- [ ] マスクキーは予測不可能である必要がある (Section 5.3)
|
|
161
|
+
|
|
162
|
+
### 推奨要件 (SHOULD)
|
|
163
|
+
- [ ] Close フレームには理由を含める (Section 7.1.6)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## 開発
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# 依存関係インストール
|
|
170
|
+
npm install
|
|
171
|
+
|
|
172
|
+
# 開発モード
|
|
173
|
+
npm run dev
|
|
174
|
+
|
|
175
|
+
# ビルド
|
|
176
|
+
npm run build
|
|
177
|
+
|
|
178
|
+
# テスト
|
|
179
|
+
npm test
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## ライセンス
|
|
183
|
+
|
|
184
|
+
MIT
|
|
185
|
+
|
|
186
|
+
## 関連プロジェクト
|
|
187
|
+
|
|
188
|
+
- [mjpitz/mcp-rfc](https://github.com/mjpitz/mcp-rfc) - テキストベースの RFC MCP
|
|
189
|
+
- [ietf-tools/RFCXML](https://github.com/ietf-tools/RFCXML) - RFCXML スキーマ
|
|
190
|
+
- [xml2rfc](https://xml2rfc.ietf.org/) - IETF 公式ツール
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* RFCXML MCP Server
|
|
4
|
+
* RFC 文書を構造的に理解するための MCP サーバー
|
|
5
|
+
*/
|
|
6
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
7
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
+
import { tools } from './tools/definitions.js';
|
|
10
|
+
import { handleGetRFCStructure, handleGetRequirements, handleGetDefinitions, handleGetDependencies, handleGetRelatedSections, handleGenerateChecklist, handleValidateStatement, } from './tools/handlers.js';
|
|
11
|
+
// サーバーインスタンス
|
|
12
|
+
const server = new Server({
|
|
13
|
+
name: 'rfcxml-mcp',
|
|
14
|
+
version: '0.1.0',
|
|
15
|
+
}, {
|
|
16
|
+
capabilities: {
|
|
17
|
+
tools: {},
|
|
18
|
+
resources: {},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
// ツール一覧
|
|
22
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
23
|
+
return { tools };
|
|
24
|
+
});
|
|
25
|
+
// ツール実行
|
|
26
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
27
|
+
const { name, arguments: args } = request.params;
|
|
28
|
+
try {
|
|
29
|
+
let result;
|
|
30
|
+
switch (name) {
|
|
31
|
+
case 'get_rfc_structure':
|
|
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}`);
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
content: [
|
|
57
|
+
{
|
|
58
|
+
type: 'text',
|
|
59
|
+
text: JSON.stringify(result, null, 2),
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
66
|
+
return {
|
|
67
|
+
content: [
|
|
68
|
+
{
|
|
69
|
+
type: 'text',
|
|
70
|
+
text: JSON.stringify({ error: message }, null, 2),
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
isError: true,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// リソース一覧(RFC スキーマ)
|
|
78
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
79
|
+
return {
|
|
80
|
+
resources: [
|
|
81
|
+
{
|
|
82
|
+
uri: 'rfcxml://schema',
|
|
83
|
+
name: 'RFCXML Schema Information',
|
|
84
|
+
description: 'RFCXML v3 の構造とスキーマ情報',
|
|
85
|
+
mimeType: 'application/json',
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
// リソース読み取り
|
|
91
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
92
|
+
const { uri } = request.params;
|
|
93
|
+
if (uri === 'rfcxml://schema') {
|
|
94
|
+
return {
|
|
95
|
+
contents: [
|
|
96
|
+
{
|
|
97
|
+
uri,
|
|
98
|
+
mimeType: 'application/json',
|
|
99
|
+
text: JSON.stringify({
|
|
100
|
+
version: 'v3',
|
|
101
|
+
spec: 'RFC 7991 (superseded by rfc7991bis)',
|
|
102
|
+
documentation: 'https://authors.ietf.org/rfcxml-vocabulary',
|
|
103
|
+
keyElements: {
|
|
104
|
+
bcp14: 'RFC 2119 キーワード(MUST, SHOULD, MAY 等)をマークアップ',
|
|
105
|
+
xref: '内部・外部参照',
|
|
106
|
+
reference: '参考文献',
|
|
107
|
+
section: 'セクション構造',
|
|
108
|
+
t: 'テキストパラグラフ',
|
|
109
|
+
dl: '定義リスト',
|
|
110
|
+
sourcecode: 'ソースコード',
|
|
111
|
+
},
|
|
112
|
+
}, null, 2),
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
throw new Error(`Unknown resource: ${uri}`);
|
|
118
|
+
});
|
|
119
|
+
// サーバー起動
|
|
120
|
+
async function main() {
|
|
121
|
+
const transport = new StdioServerTransport();
|
|
122
|
+
await server.connect(transport);
|
|
123
|
+
console.error('RFCXML MCP Server started');
|
|
124
|
+
}
|
|
125
|
+
main().catch((error) => {
|
|
126
|
+
console.error('Server error:', error);
|
|
127
|
+
process.exit(1);
|
|
128
|
+
});
|
|
129
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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,EACL,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAE7B,aAAa;AACb,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;IACE,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,EAAE;KACd;CACF,CACF,CAAC;AAEF,QAAQ;AACR,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC,CAAC,CAAC;AAEH,QAAQ;AACR,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAEjD,IAAI,CAAC;QACH,IAAI,MAAe,CAAC;QAEpB,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,mBAAmB;gBACtB,MAAM,GAAG,MAAM,qBAAqB,CAAC,IAAW,CAAC,CAAC;gBAClD,MAAM;YAER,KAAK,kBAAkB;gBACrB,MAAM,GAAG,MAAM,qBAAqB,CAAC,IAAW,CAAC,CAAC;gBAClD,MAAM;YAER,KAAK,iBAAiB;gBACpB,MAAM,GAAG,MAAM,oBAAoB,CAAC,IAAW,CAAC,CAAC;gBACjD,MAAM;YAER,KAAK,sBAAsB;gBACzB,MAAM,GAAG,MAAM,qBAAqB,CAAC,IAAW,CAAC,CAAC;gBAClD,MAAM;YAER,KAAK,sBAAsB;gBACzB,MAAM,GAAG,MAAM,wBAAwB,CAAC,IAAW,CAAC,CAAC;gBACrD,MAAM;YAER,KAAK,oBAAoB;gBACvB,MAAM,GAAG,MAAM,uBAAuB,CAAC,IAAW,CAAC,CAAC;gBACpD,MAAM;YAER,KAAK,oBAAoB;gBACvB,MAAM,GAAG,MAAM,uBAAuB,CAAC,IAAW,CAAC,CAAC;gBACpD,MAAM;YAER;gBACE,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBACtC;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;iBAClD;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,mBAAmB;AACnB,MAAM,CAAC,iBAAiB,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;IAC9D,OAAO;QACL,SAAS,EAAE;YACT;gBACE,GAAG,EAAE,iBAAiB;gBACtB,IAAI,EAAE,2BAA2B;gBACjC,WAAW,EAAE,sBAAsB;gBACnC,QAAQ,EAAE,kBAAkB;aAC7B;SACF;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,WAAW;AACX,MAAM,CAAC,iBAAiB,CAAC,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IACpE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAE/B,IAAI,GAAG,KAAK,iBAAiB,EAAE,CAAC;QAC9B,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG;oBACH,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,OAAO,EAAE,IAAI;wBACb,IAAI,EAAE,qCAAqC;wBAC3C,aAAa,EAAE,4CAA4C;wBAC3D,WAAW,EAAE;4BACX,KAAK,EAAE,4CAA4C;4BACnD,IAAI,EAAE,SAAS;4BACf,SAAS,EAAE,MAAM;4BACjB,OAAO,EAAE,SAAS;4BAClB,CAAC,EAAE,WAAW;4BACd,EAAE,EAAE,OAAO;4BACX,UAAU,EAAE,QAAQ;yBACrB;qBACF,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;AAC9C,CAAC,CAAC,CAAC;AAEH,SAAS;AACT,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;AAC7C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 取得サービス
|
|
3
|
+
* RFCXML ソースの取得とキャッシュ管理
|
|
4
|
+
*/
|
|
5
|
+
import type { RFCMetadata } from '../types/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* RFCXML を取得
|
|
8
|
+
*/
|
|
9
|
+
export declare function fetchRFCXML(rfcNumber: number): Promise<string>;
|
|
10
|
+
/**
|
|
11
|
+
* RFC メタデータを取得(IETF Datatracker API)
|
|
12
|
+
*/
|
|
13
|
+
export declare function fetchRFCMetadata(rfcNumber: number): Promise<RFCMetadata>;
|
|
14
|
+
/**
|
|
15
|
+
* RFC テキストを取得
|
|
16
|
+
*/
|
|
17
|
+
export declare function fetchRFCText(rfcNumber: number): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* RFC が XML 形式で利用可能か確認
|
|
20
|
+
* 注: RFC 8650 (2019年12月) 以降は公式に RFCXML v3
|
|
21
|
+
*/
|
|
22
|
+
export declare function isRFCXMLAvailable(rfcNumber: number): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* RFC XML 取得エラー
|
|
25
|
+
*/
|
|
26
|
+
export declare class RFCXMLNotAvailableError extends Error {
|
|
27
|
+
readonly rfcNumber: number;
|
|
28
|
+
readonly isOldRFC: boolean;
|
|
29
|
+
readonly suggestion: string;
|
|
30
|
+
constructor(rfcNumber: number, originalErrors?: string[]);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* キャッシュクリア
|
|
34
|
+
*/
|
|
35
|
+
export declare function clearCache(): void;
|
|
36
|
+
//# sourceMappingURL=rfc-fetcher.d.ts.map
|
|
@@ -0,0 +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;AA6BrD;;GAEG;AACH,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwCpE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAoD9E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwCrE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAI5D;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;CAmB7D;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAIjC"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 取得サービス
|
|
3
|
+
* RFCXML ソースの取得とキャッシュ管理
|
|
4
|
+
*/
|
|
5
|
+
// キャッシュ(メモリ内)
|
|
6
|
+
const xmlCache = new Map();
|
|
7
|
+
const textCache = new Map();
|
|
8
|
+
const metadataCache = new Map();
|
|
9
|
+
/**
|
|
10
|
+
* RFC XML ソースの取得元
|
|
11
|
+
*/
|
|
12
|
+
const RFC_XML_SOURCES = {
|
|
13
|
+
// RFC Editor 公式
|
|
14
|
+
rfcEditor: (num) => `https://www.rfc-editor.org/rfc/rfc${num}.xml`,
|
|
15
|
+
// IETF Tools
|
|
16
|
+
ietfTools: (num) => `https://xml2rfc.ietf.org/public/rfc/rfc${num}.xml`,
|
|
17
|
+
// Datatracker
|
|
18
|
+
datatracker: (num) => `https://datatracker.ietf.org/doc/rfc${num}/xml/`,
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* RFC テキストソースの取得元
|
|
22
|
+
*/
|
|
23
|
+
const RFC_TEXT_SOURCES = {
|
|
24
|
+
// RFC Editor 公式(テキスト)
|
|
25
|
+
rfcEditor: (num) => `https://www.rfc-editor.org/rfc/rfc${num}.txt`,
|
|
26
|
+
// IETF Tools
|
|
27
|
+
ietfTools: (num) => `https://tools.ietf.org/rfc/rfc${num}.txt`,
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* RFCXML を取得
|
|
31
|
+
*/
|
|
32
|
+
export async function fetchRFCXML(rfcNumber) {
|
|
33
|
+
// キャッシュチェック
|
|
34
|
+
const cached = xmlCache.get(rfcNumber);
|
|
35
|
+
if (cached) {
|
|
36
|
+
return cached;
|
|
37
|
+
}
|
|
38
|
+
// 複数ソースを試行
|
|
39
|
+
const errors = [];
|
|
40
|
+
for (const [sourceName, urlFn] of Object.entries(RFC_XML_SOURCES)) {
|
|
41
|
+
try {
|
|
42
|
+
const url = urlFn(rfcNumber);
|
|
43
|
+
const response = await fetch(url, {
|
|
44
|
+
headers: {
|
|
45
|
+
Accept: 'application/xml, text/xml',
|
|
46
|
+
'User-Agent': 'rfcxml-mcp/0.1.0',
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
if (response.ok) {
|
|
50
|
+
const xml = await response.text();
|
|
51
|
+
// 基本的な XML 検証
|
|
52
|
+
if (xml.includes('<?xml') || xml.includes('<rfc')) {
|
|
53
|
+
xmlCache.set(rfcNumber, xml);
|
|
54
|
+
console.error(`[RFC ${rfcNumber}] Fetched from ${sourceName}`);
|
|
55
|
+
return xml;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
errors.push(error);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// すべて失敗した場合
|
|
64
|
+
throw new RFCXMLNotAvailableError(rfcNumber, errors.map((e) => e.message));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* RFC メタデータを取得(IETF Datatracker API)
|
|
68
|
+
*/
|
|
69
|
+
export async function fetchRFCMetadata(rfcNumber) {
|
|
70
|
+
// キャッシュチェック
|
|
71
|
+
const cached = metadataCache.get(rfcNumber);
|
|
72
|
+
if (cached) {
|
|
73
|
+
return cached;
|
|
74
|
+
}
|
|
75
|
+
const url = `https://datatracker.ietf.org/api/v1/doc/document/rfc${rfcNumber}/`;
|
|
76
|
+
try {
|
|
77
|
+
const response = await fetch(url, {
|
|
78
|
+
headers: {
|
|
79
|
+
Accept: 'application/json',
|
|
80
|
+
'User-Agent': 'rfcxml-mcp/0.1.0',
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
throw new Error(`HTTP ${response.status}`);
|
|
85
|
+
}
|
|
86
|
+
const data = (await response.json());
|
|
87
|
+
const metadata = {
|
|
88
|
+
number: rfcNumber,
|
|
89
|
+
title: data.title || `RFC ${rfcNumber}`,
|
|
90
|
+
authors: [], // TODO: 別 API から取得
|
|
91
|
+
date: data.time || '',
|
|
92
|
+
category: mapCategory(data.std_level ?? null),
|
|
93
|
+
stream: mapStream(data.stream ?? null),
|
|
94
|
+
abstract: data.abstract || undefined,
|
|
95
|
+
};
|
|
96
|
+
metadataCache.set(rfcNumber, metadata);
|
|
97
|
+
return metadata;
|
|
98
|
+
}
|
|
99
|
+
catch (_error) {
|
|
100
|
+
// フォールバック: 最小限のメタデータ
|
|
101
|
+
return {
|
|
102
|
+
number: rfcNumber,
|
|
103
|
+
title: `RFC ${rfcNumber}`,
|
|
104
|
+
authors: [],
|
|
105
|
+
date: '',
|
|
106
|
+
category: 'info',
|
|
107
|
+
stream: 'IETF',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* RFC テキストを取得
|
|
113
|
+
*/
|
|
114
|
+
export async function fetchRFCText(rfcNumber) {
|
|
115
|
+
// キャッシュチェック
|
|
116
|
+
const cached = textCache.get(rfcNumber);
|
|
117
|
+
if (cached) {
|
|
118
|
+
return cached;
|
|
119
|
+
}
|
|
120
|
+
// 複数ソースを試行
|
|
121
|
+
const errors = [];
|
|
122
|
+
for (const [sourceName, urlFn] of Object.entries(RFC_TEXT_SOURCES)) {
|
|
123
|
+
try {
|
|
124
|
+
const url = urlFn(rfcNumber);
|
|
125
|
+
const response = await fetch(url, {
|
|
126
|
+
headers: {
|
|
127
|
+
Accept: 'text/plain',
|
|
128
|
+
'User-Agent': 'rfcxml-mcp/0.1.0',
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
if (response.ok) {
|
|
132
|
+
const text = await response.text();
|
|
133
|
+
// 基本的な検証(RFCテキストの特徴を確認)
|
|
134
|
+
if (text.includes('Request for Comments') || text.includes('RFC ')) {
|
|
135
|
+
textCache.set(rfcNumber, text);
|
|
136
|
+
console.error(`[RFC ${rfcNumber}] Text fetched from ${sourceName}`);
|
|
137
|
+
return text;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
errors.push(error);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// すべて失敗
|
|
146
|
+
throw new Error(`Failed to fetch RFC ${rfcNumber} text from all sources. ` +
|
|
147
|
+
`Errors: ${errors.map((e) => e.message).join(', ')}`);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* RFC が XML 形式で利用可能か確認
|
|
151
|
+
* 注: RFC 8650 (2019年12月) 以降は公式に RFCXML v3
|
|
152
|
+
*/
|
|
153
|
+
export function isRFCXMLAvailable(rfcNumber) {
|
|
154
|
+
// RFC 8650 以降は確実に RFCXML v3 が利用可能
|
|
155
|
+
// それ以前は一部のみ利用可能
|
|
156
|
+
return rfcNumber >= 8650;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* RFC XML 取得エラー
|
|
160
|
+
*/
|
|
161
|
+
export class RFCXMLNotAvailableError extends Error {
|
|
162
|
+
rfcNumber;
|
|
163
|
+
isOldRFC;
|
|
164
|
+
suggestion;
|
|
165
|
+
constructor(rfcNumber, originalErrors = []) {
|
|
166
|
+
const isOldRFC = rfcNumber < 8650;
|
|
167
|
+
const suggestion = isOldRFC
|
|
168
|
+
? `RFC ${rfcNumber} は RFCXML v3 より前の形式で公開されているため、XML が利用できない可能性があります。` +
|
|
169
|
+
`テキスト形式での取得を検討してください(ietf MCP の get_ietf_doc を使用)。`
|
|
170
|
+
: `RFC ${rfcNumber} の XML 取得に失敗しました。ネットワーク接続を確認してください。`;
|
|
171
|
+
super(`RFC ${rfcNumber} XML を取得できませんでした。\n` +
|
|
172
|
+
`理由: ${isOldRFC ? '古い RFC (< 8650) のため XML が利用できない可能性があります' : 'ネットワークエラー'}\n` +
|
|
173
|
+
`提案: ${suggestion}` +
|
|
174
|
+
(originalErrors.length > 0 ? `\n詳細: ${originalErrors.join(', ')}` : ''));
|
|
175
|
+
this.name = 'RFCXMLNotAvailableError';
|
|
176
|
+
this.rfcNumber = rfcNumber;
|
|
177
|
+
this.isOldRFC = isOldRFC;
|
|
178
|
+
this.suggestion = suggestion;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* キャッシュクリア
|
|
183
|
+
*/
|
|
184
|
+
export function clearCache() {
|
|
185
|
+
xmlCache.clear();
|
|
186
|
+
textCache.clear();
|
|
187
|
+
metadataCache.clear();
|
|
188
|
+
}
|
|
189
|
+
// ヘルパー関数
|
|
190
|
+
function mapCategory(stdLevel) {
|
|
191
|
+
switch (stdLevel?.toLowerCase()) {
|
|
192
|
+
case 'proposed standard':
|
|
193
|
+
case 'draft standard':
|
|
194
|
+
case 'internet standard':
|
|
195
|
+
return 'std';
|
|
196
|
+
case 'best current practice':
|
|
197
|
+
return 'bcp';
|
|
198
|
+
case 'experimental':
|
|
199
|
+
return 'exp';
|
|
200
|
+
case 'historic':
|
|
201
|
+
return 'historic';
|
|
202
|
+
default:
|
|
203
|
+
return 'info';
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function mapStream(stream) {
|
|
207
|
+
switch (stream?.toLowerCase()) {
|
|
208
|
+
case 'ietf':
|
|
209
|
+
return 'IETF';
|
|
210
|
+
case 'iab':
|
|
211
|
+
return 'IAB';
|
|
212
|
+
case 'irtf':
|
|
213
|
+
return 'IRTF';
|
|
214
|
+
case 'ise':
|
|
215
|
+
return 'independent';
|
|
216
|
+
default:
|
|
217
|
+
return 'IETF';
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=rfc-fetcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rfc-fetcher.js","sourceRoot":"","sources":["../../src/services/rfc-fetcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC テキストパーサー
|
|
3
|
+
* XMLが利用できない古いRFC用のフォールバック解析
|
|
4
|
+
*/
|
|
5
|
+
import type { Section, Requirement, RequirementLevel } from '../types/index.js';
|
|
6
|
+
import type { ParsedRFC } from './rfcxml-parser.js';
|
|
7
|
+
/**
|
|
8
|
+
* RFC テキストをパースして構造化データに変換(中精度)
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseRFCText(text: string, rfcNumber: number): ParsedRFC;
|
|
11
|
+
/**
|
|
12
|
+
* テキストから要件を抽出
|
|
13
|
+
*/
|
|
14
|
+
export declare function extractTextRequirements(sections: Section[], filter?: {
|
|
15
|
+
section?: string;
|
|
16
|
+
level?: RequirementLevel;
|
|
17
|
+
}): Requirement[];
|
|
18
|
+
//# sourceMappingURL=rfc-text-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rfc-text-parser.d.ts","sourceRoot":"","sources":["../../src/services/rfc-text-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,OAAO,EACP,WAAW,EACX,gBAAgB,EAIjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAmBpD;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAYvE;AAyMD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,OAAO,EAAE,EACnB,MAAM,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,gBAAgB,CAAA;CAAE,GACtD,WAAW,EAAE,CA0Cf"}
|