@pipeworx/mcp-openrouter 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 +21 -0
- package/README.md +55 -0
- package/package.json +20 -0
- package/server.json +18 -0
- package/src/index.ts +311 -0
- package/tsconfig.json +14 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pipeworx
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# mcp-openrouter
|
|
2
|
+
|
|
3
|
+
OpenRouter Models MCP.
|
|
4
|
+
|
|
5
|
+
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 873+ live data sources.
|
|
6
|
+
|
|
7
|
+
## Tools
|
|
8
|
+
|
|
9
|
+
| Tool | Description |
|
|
10
|
+
|------|-------------|
|
|
11
|
+
|
|
12
|
+
## Quick Start
|
|
13
|
+
|
|
14
|
+
Add to your MCP client (Claude Desktop, Cursor, Windsurf, etc.):
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"mcpServers": {
|
|
19
|
+
"openrouter": {
|
|
20
|
+
"url": "https://gateway.pipeworx.io/openrouter/mcp"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or connect to the full Pipeworx gateway for access to all 873+ data sources:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"mcpServers": {
|
|
31
|
+
"pipeworx": {
|
|
32
|
+
"url": "https://gateway.pipeworx.io/mcp"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Using with ask_pipeworx
|
|
39
|
+
|
|
40
|
+
Instead of calling tools directly, you can ask questions in plain English:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
ask_pipeworx({ question: "your question about Openrouter data" })
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The gateway picks the right tool and fills the arguments automatically.
|
|
47
|
+
|
|
48
|
+
## More
|
|
49
|
+
|
|
50
|
+
- [All tools and guides](https://github.com/pipeworx-io/examples)
|
|
51
|
+
- [pipeworx.io](https://pipeworx.io)
|
|
52
|
+
|
|
53
|
+
## License
|
|
54
|
+
|
|
55
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pipeworx/mcp-openrouter",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "OpenRouter Models MCP.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"types": "src/index.ts",
|
|
8
|
+
"keywords": ["mcp", "mcp-server", "model-context-protocol", "pipeworx", "openrouter"],
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/pipeworx-io/mcp-openrouter"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"typecheck": "tsc --noEmit"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"typescript": "^5.7.0"
|
|
19
|
+
}
|
|
20
|
+
}
|
package/server.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.pipeworx-io/openrouter",
|
|
4
|
+
"title": "Openrouter",
|
|
5
|
+
"description": "OpenRouter Models MCP.",
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"websiteUrl": "https://pipeworx.io/packs/openrouter",
|
|
8
|
+
"repository": {
|
|
9
|
+
"url": "https://github.com/pipeworx-io/mcp-openrouter",
|
|
10
|
+
"source": "github"
|
|
11
|
+
},
|
|
12
|
+
"remotes": [
|
|
13
|
+
{
|
|
14
|
+
"type": "streamable-http",
|
|
15
|
+
"url": "https://gateway.pipeworx.io/openrouter/mcp"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
interface McpToolDefinition {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: 'object';
|
|
6
|
+
properties: Record<string, unknown>;
|
|
7
|
+
required?: string[];
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface McpToolExport {
|
|
12
|
+
tools: McpToolDefinition[];
|
|
13
|
+
callTool: (name: string, args: Record<string, unknown>) => Promise<unknown>;
|
|
14
|
+
meter?: { credits: number };
|
|
15
|
+
cost?: Record<string, unknown>;
|
|
16
|
+
provider?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* OpenRouter Models MCP.
|
|
21
|
+
*
|
|
22
|
+
* Keyless catalog of ~340 LLMs across every major provider (Anthropic, OpenAI,
|
|
23
|
+
* Google, Meta, Mistral, DeepSeek, xAI, and more) via the OpenRouter models API
|
|
24
|
+
* (openrouter.ai/api/v1). Live cross-provider PRICING, context windows, and
|
|
25
|
+
* capabilities — answers "which models exist, how much do they cost, how big is
|
|
26
|
+
* their context window". Pricing is normalized to $ per 1M tokens for
|
|
27
|
+
* readability. Keyless.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
const BASE = 'https://openrouter.ai/api/v1';
|
|
32
|
+
const UA = 'pipeworx/1.0 (+https://pipeworx.io)';
|
|
33
|
+
|
|
34
|
+
interface RawModel {
|
|
35
|
+
id: string;
|
|
36
|
+
canonical_slug?: string;
|
|
37
|
+
name?: string;
|
|
38
|
+
created?: number;
|
|
39
|
+
description?: string;
|
|
40
|
+
context_length?: number;
|
|
41
|
+
architecture?: {
|
|
42
|
+
modality?: string;
|
|
43
|
+
input_modalities?: string[];
|
|
44
|
+
output_modalities?: string[];
|
|
45
|
+
tokenizer?: string;
|
|
46
|
+
};
|
|
47
|
+
pricing?: {
|
|
48
|
+
prompt?: string;
|
|
49
|
+
completion?: string;
|
|
50
|
+
request?: string;
|
|
51
|
+
image?: string;
|
|
52
|
+
web_search?: string;
|
|
53
|
+
input_cache_read?: string;
|
|
54
|
+
input_cache_write?: string;
|
|
55
|
+
};
|
|
56
|
+
top_provider?: {
|
|
57
|
+
context_length?: number;
|
|
58
|
+
max_completion_tokens?: number;
|
|
59
|
+
is_moderated?: boolean;
|
|
60
|
+
};
|
|
61
|
+
supported_parameters?: string[];
|
|
62
|
+
knowledge_cutoff?: string | null;
|
|
63
|
+
hugging_face_id?: string | null;
|
|
64
|
+
per_request_limits?: unknown;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const tools: McpToolExport['tools'] = [
|
|
68
|
+
{
|
|
69
|
+
name: 'list_models',
|
|
70
|
+
description:
|
|
71
|
+
'List LLMs from the OpenRouter catalog (~340 models across all major providers) with normalized $/1M-token pricing, context windows, and modality. Filter by search, free-only, minimum context, or modality (e.g. "image" for vision models). Sorted cheapest-first by completion price. Keyless.',
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: 'object',
|
|
74
|
+
properties: {
|
|
75
|
+
search: {
|
|
76
|
+
type: 'string',
|
|
77
|
+
description: 'Case-insensitive substring match against model id, name, and description. e.g. "claude", "gpt-4o", "deepseek".',
|
|
78
|
+
},
|
|
79
|
+
free_only: {
|
|
80
|
+
type: 'boolean',
|
|
81
|
+
description: 'If true, only return models whose prompt price is $0 (free tier).',
|
|
82
|
+
},
|
|
83
|
+
min_context: {
|
|
84
|
+
type: 'number',
|
|
85
|
+
description: 'Minimum context_length in tokens, e.g. 100000 or 200000.',
|
|
86
|
+
},
|
|
87
|
+
modality: {
|
|
88
|
+
type: 'string',
|
|
89
|
+
description: 'Substring match on architecture.modality, e.g. "image" to find vision/multimodal models, "text->text" for text-only.',
|
|
90
|
+
},
|
|
91
|
+
limit: {
|
|
92
|
+
type: 'number',
|
|
93
|
+
description: 'Max models to return (default 25, max 60).',
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'get_model',
|
|
100
|
+
description:
|
|
101
|
+
'Get full details for one OpenRouter model by id — normalized $/1M pricing (prompt, completion, plus per-request/image/web-search costs), context window, modality, supported parameters, tokenizer, knowledge cutoff. e.g. id "anthropic/claude-sonnet-4.5". Keyless.',
|
|
102
|
+
inputSchema: {
|
|
103
|
+
type: 'object',
|
|
104
|
+
properties: {
|
|
105
|
+
id: {
|
|
106
|
+
type: 'string',
|
|
107
|
+
description: 'Exact model id, e.g. "anthropic/claude-sonnet-4.5", "openai/gpt-4o", "google/gemini-2.5-pro".',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
required: ['id'],
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'compare_models',
|
|
115
|
+
description:
|
|
116
|
+
'Side-by-side comparison of pricing ($/1M tokens), context window, and modality for 2-5 OpenRouter models. Answers "is claude-sonnet-4.5 cheaper than gpt-4o". Keyless.',
|
|
117
|
+
inputSchema: {
|
|
118
|
+
type: 'object',
|
|
119
|
+
properties: {
|
|
120
|
+
ids: {
|
|
121
|
+
type: 'array',
|
|
122
|
+
items: { type: 'string' },
|
|
123
|
+
description: 'Array of 2-5 exact model ids, e.g. ["anthropic/claude-sonnet-4.5", "openai/gpt-4o"].',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
required: ['ids'],
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
async function callTool(name: string, args: Record<string, unknown>): Promise<unknown> {
|
|
132
|
+
try {
|
|
133
|
+
switch (name) {
|
|
134
|
+
case 'list_models':
|
|
135
|
+
return listModels(args);
|
|
136
|
+
case 'get_model':
|
|
137
|
+
return getModel(args);
|
|
138
|
+
case 'compare_models':
|
|
139
|
+
return compareModels(args);
|
|
140
|
+
default:
|
|
141
|
+
return { error: `Unknown tool: ${name}` };
|
|
142
|
+
}
|
|
143
|
+
} catch (e) {
|
|
144
|
+
return { error: e instanceof Error ? e.message : String(e) };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Convert a per-token price string to $ per 1M tokens, rounded to 4dp. null if missing. */
|
|
149
|
+
function perMillion(priceStr: string | undefined): number | null {
|
|
150
|
+
if (priceStr === undefined || priceStr === null || priceStr === '') return null;
|
|
151
|
+
const n = Number(priceStr);
|
|
152
|
+
if (!Number.isFinite(n)) return null;
|
|
153
|
+
return Math.round(n * 1_000_000 * 1e4) / 1e4;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function provider(id: string): string {
|
|
157
|
+
const i = id.indexOf('/');
|
|
158
|
+
return i > 0 ? id.slice(0, i) : id;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Map a raw model into a compact record (full=false) or a detailed one (full=true). */
|
|
162
|
+
function mapModel(raw: RawModel, opts: { full?: boolean } = {}): Record<string, unknown> {
|
|
163
|
+
const pricing = raw.pricing ?? {};
|
|
164
|
+
const arch = raw.architecture ?? {};
|
|
165
|
+
const promptPer1m = perMillion(pricing.prompt);
|
|
166
|
+
const completionPer1m = perMillion(pricing.completion);
|
|
167
|
+
const isFree = Number(pricing.prompt ?? NaN) === 0;
|
|
168
|
+
|
|
169
|
+
if (!opts.full) {
|
|
170
|
+
return {
|
|
171
|
+
id: raw.id,
|
|
172
|
+
name: raw.name,
|
|
173
|
+
context_length: raw.context_length ?? null,
|
|
174
|
+
prompt_per_1m: promptPer1m,
|
|
175
|
+
completion_per_1m: completionPer1m,
|
|
176
|
+
is_free: isFree,
|
|
177
|
+
modality: arch.modality ?? null,
|
|
178
|
+
provider: provider(raw.id),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const tp = raw.top_provider ?? {};
|
|
183
|
+
let description = raw.description ?? '';
|
|
184
|
+
if (description.length > 500) description = `${description.slice(0, 500)}…`;
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
id: raw.id,
|
|
188
|
+
name: raw.name,
|
|
189
|
+
description,
|
|
190
|
+
context_length: raw.context_length ?? null,
|
|
191
|
+
pricing: {
|
|
192
|
+
prompt_per_1m: promptPer1m,
|
|
193
|
+
completion_per_1m: completionPer1m,
|
|
194
|
+
input_cache_read_per_1m: perMillion(pricing.input_cache_read),
|
|
195
|
+
input_cache_write_per_1m: perMillion(pricing.input_cache_write),
|
|
196
|
+
request: pricing.request ?? null,
|
|
197
|
+
image: pricing.image ?? null,
|
|
198
|
+
web_search: pricing.web_search ?? null,
|
|
199
|
+
},
|
|
200
|
+
architecture: {
|
|
201
|
+
modality: arch.modality ?? null,
|
|
202
|
+
input_modalities: arch.input_modalities ?? null,
|
|
203
|
+
output_modalities: arch.output_modalities ?? null,
|
|
204
|
+
tokenizer: arch.tokenizer ?? null,
|
|
205
|
+
},
|
|
206
|
+
top_provider: {
|
|
207
|
+
context_length: tp.context_length ?? null,
|
|
208
|
+
max_completion_tokens: tp.max_completion_tokens ?? null,
|
|
209
|
+
is_moderated: tp.is_moderated ?? null,
|
|
210
|
+
},
|
|
211
|
+
supported_parameters: raw.supported_parameters ?? [],
|
|
212
|
+
knowledge_cutoff: raw.knowledge_cutoff ?? null,
|
|
213
|
+
hugging_face_id: raw.hugging_face_id ?? null,
|
|
214
|
+
created: raw.created ? new Date(raw.created * 1000).toISOString() : null,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
let _cache: RawModel[] | null = null;
|
|
219
|
+
/** Fetch + cache the models list within a single call. */
|
|
220
|
+
async function orGet(): Promise<RawModel[]> {
|
|
221
|
+
if (_cache) return _cache;
|
|
222
|
+
const res = await fetch(`${BASE}/models`, {
|
|
223
|
+
headers: { Accept: 'application/json', 'User-Agent': UA },
|
|
224
|
+
});
|
|
225
|
+
if (!res.ok) throw new Error(`openrouter: ${res.status} ${(await res.text()).slice(0, 200)}`);
|
|
226
|
+
const body = (await res.json()) as { data?: RawModel[] };
|
|
227
|
+
_cache = Array.isArray(body.data) ? body.data : [];
|
|
228
|
+
return _cache;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async function listModels(args: Record<string, unknown>): Promise<unknown> {
|
|
232
|
+
const all = await orGet();
|
|
233
|
+
|
|
234
|
+
const search = typeof args.search === 'string' ? args.search.trim().toLowerCase() : '';
|
|
235
|
+
const freeOnly = args.free_only === true;
|
|
236
|
+
const minContext = typeof args.min_context === 'number' ? args.min_context : 0;
|
|
237
|
+
const modality = typeof args.modality === 'string' ? args.modality.trim().toLowerCase() : '';
|
|
238
|
+
let limit = typeof args.limit === 'number' ? Math.floor(args.limit) : 25;
|
|
239
|
+
if (!Number.isFinite(limit) || limit < 1) limit = 25;
|
|
240
|
+
if (limit > 60) limit = 60;
|
|
241
|
+
|
|
242
|
+
let filtered = all.filter((m) => {
|
|
243
|
+
if (search) {
|
|
244
|
+
const hay = `${m.id} ${m.name ?? ''} ${m.description ?? ''}`.toLowerCase();
|
|
245
|
+
if (!hay.includes(search)) return false;
|
|
246
|
+
}
|
|
247
|
+
if (freeOnly && Number(m.pricing?.prompt ?? NaN) !== 0) return false;
|
|
248
|
+
if (minContext && (m.context_length ?? 0) < minContext) return false;
|
|
249
|
+
if (modality && !(m.architecture?.modality ?? '').toLowerCase().includes(modality)) return false;
|
|
250
|
+
return true;
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// Sort cheapest-first by completion price ($/1M); nulls last.
|
|
254
|
+
filtered = filtered.sort((a, b) => {
|
|
255
|
+
const av = perMillion(a.pricing?.completion);
|
|
256
|
+
const bv = perMillion(b.pricing?.completion);
|
|
257
|
+
if (av === null && bv === null) return 0;
|
|
258
|
+
if (av === null) return 1;
|
|
259
|
+
if (bv === null) return -1;
|
|
260
|
+
return av - bv;
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
const models = filtered.slice(0, limit).map((m) => mapModel(m));
|
|
264
|
+
return { total_available: all.length, count: models.length, models };
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
async function getModel(args: Record<string, unknown>): Promise<unknown> {
|
|
268
|
+
const id = typeof args.id === 'string' ? args.id.trim() : '';
|
|
269
|
+
if (!id) return { error: 'provide a model id, e.g. "anthropic/claude-sonnet-4.5"', id: args.id ?? null };
|
|
270
|
+
|
|
271
|
+
const all = await orGet();
|
|
272
|
+
const raw = all.find((m) => m.id === id);
|
|
273
|
+
if (!raw) return { error: 'model not found', id };
|
|
274
|
+
return mapModel(raw, { full: true });
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async function compareModels(args: Record<string, unknown>): Promise<unknown> {
|
|
278
|
+
const ids = Array.isArray(args.ids) ? args.ids.filter((x): x is string => typeof x === 'string') : [];
|
|
279
|
+
if (ids.length < 2 || ids.length > 5) {
|
|
280
|
+
return { error: 'provide 2-5 model ids', ids };
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const all = await orGet();
|
|
284
|
+
const byId = new Map(all.map((m) => [m.id, m]));
|
|
285
|
+
|
|
286
|
+
const comparison: Record<string, unknown>[] = [];
|
|
287
|
+
const notFound: string[] = [];
|
|
288
|
+
for (const id of ids) {
|
|
289
|
+
const raw = byId.get(id);
|
|
290
|
+
if (!raw) {
|
|
291
|
+
notFound.push(id);
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
const compact = mapModel(raw);
|
|
295
|
+
comparison.push({
|
|
296
|
+
id: compact.id,
|
|
297
|
+
name: compact.name,
|
|
298
|
+
context_length: compact.context_length,
|
|
299
|
+
prompt_per_1m: compact.prompt_per_1m,
|
|
300
|
+
completion_per_1m: compact.completion_per_1m,
|
|
301
|
+
modality: compact.modality,
|
|
302
|
+
is_free: compact.is_free,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const result: Record<string, unknown> = { count: comparison.length, comparison };
|
|
307
|
+
if (notFound.length) result.not_found = notFound;
|
|
308
|
+
return result;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
export default { tools, callTool, meter: { credits: 1 } } satisfies McpToolExport;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"outDir": "dist",
|
|
10
|
+
"rootDir": "src",
|
|
11
|
+
"declaration": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src"]
|
|
14
|
+
}
|