@christopher_dondici/mcp-gen 2.1.2
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/CHANGELOG.md +217 -0
- package/LICENSE +21 -0
- package/README.md +439 -0
- package/README.pt-BR.md +320 -0
- package/RELEASE_NOTES.md +98 -0
- package/SECURITY.md +75 -0
- package/SECURITY.pt-BR.md +77 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +685 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/generator.d.ts +4 -0
- package/dist/core/generator.d.ts.map +1 -0
- package/dist/core/generator.js +275 -0
- package/dist/core/generator.js.map +1 -0
- package/dist/core/incremental.d.ts +25 -0
- package/dist/core/incremental.d.ts.map +1 -0
- package/dist/core/incremental.js +91 -0
- package/dist/core/incremental.js.map +1 -0
- package/dist/core/parser.d.ts +3 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +372 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/registry.d.ts +13 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +107 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/security-lint.d.ts +53 -0
- package/dist/core/security-lint.d.ts.map +1 -0
- package/dist/core/security-lint.js +470 -0
- package/dist/core/security-lint.js.map +1 -0
- package/dist/core/security.d.ts +41 -0
- package/dist/core/security.d.ts.map +1 -0
- package/dist/core/security.js +150 -0
- package/dist/core/security.js.map +1 -0
- package/dist/core/templating.d.ts +5 -0
- package/dist/core/templating.d.ts.map +1 -0
- package/dist/core/templating.js +211 -0
- package/dist/core/templating.js.map +1 -0
- package/dist/core/types.d.ts +104 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +3 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/templates/go/Dockerfile.hbs +16 -0
- package/dist/templates/go/README.md.hbs +77 -0
- package/dist/templates/go/ci.yml.hbs +28 -0
- package/dist/templates/go/client.go.hbs +86 -0
- package/dist/templates/go/go.mod.hbs +5 -0
- package/dist/templates/go/models.go.hbs +28 -0
- package/dist/templates/go/server.go.hbs +220 -0
- package/dist/templates/python/Dockerfile.hbs +12 -0
- package/dist/templates/python/README.md.hbs +115 -0
- package/dist/templates/python/ci.yml.hbs +24 -0
- package/dist/templates/python/models.py.hbs +20 -0
- package/dist/templates/python/requirements.txt.hbs +3 -0
- package/dist/templates/python/server.py.hbs +195 -0
- package/dist/templates/typescript/Dockerfile.hbs +18 -0
- package/dist/templates/typescript/README.md.hbs +91 -0
- package/dist/templates/typescript/ci.yml.hbs +28 -0
- package/dist/templates/typescript/client.hbs +49 -0
- package/dist/templates/typescript/models.hbs +23 -0
- package/dist/templates/typescript/package.json.hbs +26 -0
- package/dist/templates/typescript/server.hbs +337 -0
- package/dist/templates/typescript/tsconfig.json.hbs +17 -0
- package/examples/petstore.json +130 -0
- package/examples/petstore.yaml +131 -0
- package/examples/week3.json +47 -0
- package/package.json +64 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Auto-generated by mcp-gen v{{generatorVersion}}
|
|
3
|
+
Spec: {{info.title}} v{{info.version}}
|
|
4
|
+
Generated: {{generatedAt}}
|
|
5
|
+
{{#if incremental}}
|
|
6
|
+
Incremental mode: edit code between @@mcp-gen markers — it will be preserved on re-generation.
|
|
7
|
+
{{/if}}
|
|
8
|
+
Base URL: {{baseUrl}}
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from mcp.server.fastmcp import FastMCP
|
|
12
|
+
from models import {{#each models}}{{name}}{{#unless @last}}, {{/unless}}{{/each}}
|
|
13
|
+
from typing import Optional, Any, Dict
|
|
14
|
+
import httpx
|
|
15
|
+
from datetime import datetime, timezone
|
|
16
|
+
|
|
17
|
+
mcp = FastMCP("{{serverName}}")
|
|
18
|
+
|
|
19
|
+
BASE_URL = "{{baseUrl}}"
|
|
20
|
+
|
|
21
|
+
_http_headers: Dict[str, str] = {}
|
|
22
|
+
{{#if requiresAuth}}
|
|
23
|
+
import os
|
|
24
|
+
_token = os.environ.get("TOKEN")
|
|
25
|
+
if _token:
|
|
26
|
+
_http_headers["Authorization"] = f"Bearer {_token}"
|
|
27
|
+
{{/if}}
|
|
28
|
+
|
|
29
|
+
RAW_CREDENTIAL_KEYS = {
|
|
30
|
+
"authorization",
|
|
31
|
+
"token",
|
|
32
|
+
"access_token",
|
|
33
|
+
"api_key",
|
|
34
|
+
"apikey",
|
|
35
|
+
"x_api_key",
|
|
36
|
+
"client_secret",
|
|
37
|
+
"refresh_token",
|
|
38
|
+
"password",
|
|
39
|
+
"secret",
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
TOOL_POLICIES = {
|
|
43
|
+
{{#each tools}}
|
|
44
|
+
"{{name}}": {
|
|
45
|
+
"endpoint": "{{method}} {{path}}",
|
|
46
|
+
"requires_ttl": True,
|
|
47
|
+
"requires_spend_limit": True,
|
|
48
|
+
"requires_request_log": True,
|
|
49
|
+
"requires_revocation_check": True,
|
|
50
|
+
},
|
|
51
|
+
{{/each}}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _normalize_key(key: str) -> str:
|
|
56
|
+
return "".join(ch for ch in key.lower() if ch.isalnum() or ch == "_")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _contains_raw_credentials(value: Any) -> bool:
|
|
60
|
+
if isinstance(value, dict):
|
|
61
|
+
for key, nested in value.items():
|
|
62
|
+
normalized = _normalize_key(str(key)).replace("-", "_")
|
|
63
|
+
for candidate in RAW_CREDENTIAL_KEYS:
|
|
64
|
+
if normalized == _normalize_key(candidate):
|
|
65
|
+
return True
|
|
66
|
+
if _contains_raw_credentials(nested):
|
|
67
|
+
return True
|
|
68
|
+
elif isinstance(value, list):
|
|
69
|
+
return any(_contains_raw_credentials(item) for item in value)
|
|
70
|
+
return False
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def ensure_no_raw_credentials(payload: Optional[dict]) -> None:
|
|
74
|
+
if payload and _contains_raw_credentials(payload):
|
|
75
|
+
raise ValueError(
|
|
76
|
+
"Raw provider credentials are not allowed in tool arguments. "
|
|
77
|
+
"Use scoped auth_context metadata only."
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _is_expired(expires_at: Optional[str]) -> bool:
|
|
82
|
+
if not expires_at:
|
|
83
|
+
return True
|
|
84
|
+
try:
|
|
85
|
+
parsed = datetime.fromisoformat(expires_at.replace("Z", "+00:00"))
|
|
86
|
+
except ValueError:
|
|
87
|
+
return True
|
|
88
|
+
if parsed.tzinfo is None:
|
|
89
|
+
parsed = parsed.replace(tzinfo=timezone.utc)
|
|
90
|
+
return parsed <= datetime.now(timezone.utc)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def require_security(tool_name: str, security: Any, auth_context: Optional[dict], request_args: Optional[dict]) -> None:
|
|
94
|
+
ensure_no_raw_credentials(request_args)
|
|
95
|
+
if auth_context is not None:
|
|
96
|
+
ensure_no_raw_credentials(auth_context)
|
|
97
|
+
|
|
98
|
+
policy = TOOL_POLICIES.get(tool_name)
|
|
99
|
+
if not policy:
|
|
100
|
+
raise ValueError(f"Missing security policy for tool: {tool_name}")
|
|
101
|
+
|
|
102
|
+
if not isinstance(auth_context, dict):
|
|
103
|
+
raise ValueError(
|
|
104
|
+
"Missing auth_context. Provide scoped metadata "
|
|
105
|
+
"(token_id, expires_at, limits, request_id) from your gateway."
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
if policy["requires_revocation_check"] and auth_context.get("revoked") is True:
|
|
109
|
+
raise PermissionError("Access revoked")
|
|
110
|
+
|
|
111
|
+
if policy["requires_ttl"] and _is_expired(auth_context.get("expires_at")):
|
|
112
|
+
raise PermissionError("Token expired or missing TTL")
|
|
113
|
+
|
|
114
|
+
if policy["requires_request_log"] and not auth_context.get("request_id"):
|
|
115
|
+
raise ValueError("request_id is required for audit logging")
|
|
116
|
+
|
|
117
|
+
if policy["requires_spend_limit"]:
|
|
118
|
+
limit = auth_context.get("spend_limit_usd")
|
|
119
|
+
used = auth_context.get("spend_used_usd")
|
|
120
|
+
if not isinstance(limit, (int, float)) or not isinstance(used, (int, float)):
|
|
121
|
+
raise ValueError("Spend limit metadata is required")
|
|
122
|
+
if used > limit:
|
|
123
|
+
raise PermissionError("Spend limit exceeded")
|
|
124
|
+
|
|
125
|
+
allowed_tools = auth_context.get("allowed_tools")
|
|
126
|
+
if isinstance(allowed_tools, list) and tool_name not in allowed_tools:
|
|
127
|
+
raise PermissionError(f"Tool not allowed by scope: {tool_name}")
|
|
128
|
+
|
|
129
|
+
endpoint_allowlist = auth_context.get("endpoint_allowlist")
|
|
130
|
+
endpoint = policy["endpoint"]
|
|
131
|
+
if isinstance(endpoint_allowlist, list) and endpoint not in endpoint_allowlist:
|
|
132
|
+
raise PermissionError(f"Endpoint not allowed: {endpoint}")
|
|
133
|
+
|
|
134
|
+
if security:
|
|
135
|
+
if not auth_context.get("token_id"):
|
|
136
|
+
raise PermissionError("Missing token_id for secured operation")
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
async def _call_api(method: str, path: str, params: dict, headers: Optional[dict] = None) -> Any:
|
|
140
|
+
"""Real HTTP call to the underlying API (used in --http mode)."""
|
|
141
|
+
url = BASE_URL.rstrip("/") + _expand_path(path, params)
|
|
142
|
+
merged_headers = dict(_http_headers)
|
|
143
|
+
if headers:
|
|
144
|
+
merged_headers.update(headers)
|
|
145
|
+
body = params.get("body")
|
|
146
|
+
async with httpx.AsyncClient() as client:
|
|
147
|
+
r = await client.request(method, url, json=body, headers=merged_headers)
|
|
148
|
+
if r.status_code >= 400:
|
|
149
|
+
raise RuntimeError(f"HTTP {r.status_code}: {r.text}")
|
|
150
|
+
try:
|
|
151
|
+
return r.json()
|
|
152
|
+
except ValueError:
|
|
153
|
+
return r.text
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def _expand_path(path: str, params: dict) -> str:
|
|
157
|
+
out = path
|
|
158
|
+
for k, v in params.items():
|
|
159
|
+
out = out.replace("{" + k + "}", str(v))
|
|
160
|
+
return out
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
# ─── Tools ───────────────────────────────────────────────────────────────────
|
|
164
|
+
|
|
165
|
+
{{#each tools}}
|
|
166
|
+
@mcp.tool()
|
|
167
|
+
async def {{name}}({{#each params}}{{name}}: {{#if required}}{{#eq type "string"}}str{{/eq}}{{#eq type "number"}}float{{/eq}}{{#eq type "boolean"}}bool{{/eq}}{{#eq type "object"}}dict{{/eq}}{{#eq type "array"}}list{{/eq}}{{else}}Optional[{{#eq type "string"}}str{{/eq}}{{#eq type "number"}}float{{/eq}}{{#eq type "boolean"}}bool{{/eq}}{{#eq type "object"}}dict{{/eq}}{{#eq type "array"}}list{{/eq}}] = None{{/if}}{{#unless @last}}, {{/unless}}{{/each}}{{#if params}}, {{/if}}auth_context: Optional[dict] = None) -> Any:
|
|
168
|
+
"""{{escapeText description}}
|
|
169
|
+
|
|
170
|
+
{{method}} {{path}}
|
|
171
|
+
"""
|
|
172
|
+
# @@mcp-gen:start:{{name}}
|
|
173
|
+
request_args = {
|
|
174
|
+
key: value
|
|
175
|
+
for key, value in locals().items()
|
|
176
|
+
if key not in {"auth_context", "request_args"}
|
|
177
|
+
}
|
|
178
|
+
require_security("{{name}}", {{#if security}}{{json security}}{{else}}None{{/if}}, auth_context, request_args)
|
|
179
|
+
{{#if ../http}}
|
|
180
|
+
return {{#if ../requiresAuth}}await _call_api("{{method}}", "{{path}}", request_args){{else}}await _call_api("{{method}}", "{{path}}", request_args){{/if}}
|
|
181
|
+
{{else}}
|
|
182
|
+
{{#if exampleResponse}}
|
|
183
|
+
return {{json exampleResponse}}
|
|
184
|
+
{{else}}
|
|
185
|
+
raise NotImplementedError("Handler not implemented: {{name}}")
|
|
186
|
+
{{/if}}
|
|
187
|
+
{{/if}}
|
|
188
|
+
# @@mcp-gen:end:{{name}}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
{{/each}}
|
|
192
|
+
# ─── Start ───────────────────────────────────────────────────────────────────
|
|
193
|
+
|
|
194
|
+
if __name__ == "__main__":
|
|
195
|
+
mcp.run()
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
FROM node:20-alpine AS builder
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
COPY package*.json ./
|
|
5
|
+
RUN npm ci --production=false
|
|
6
|
+
COPY . .
|
|
7
|
+
RUN npm run build
|
|
8
|
+
|
|
9
|
+
FROM node:20-alpine AS runtime
|
|
10
|
+
|
|
11
|
+
WORKDIR /app
|
|
12
|
+
COPY package*.json ./
|
|
13
|
+
RUN npm ci --production
|
|
14
|
+
COPY --from=builder /app/dist ./dist
|
|
15
|
+
|
|
16
|
+
ENV NODE_ENV=production
|
|
17
|
+
|
|
18
|
+
CMD ["node", "dist/server.js"]
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# {{info.title}} — MCP Server
|
|
2
|
+
|
|
3
|
+
> Generated by [mcp-gen](https://github.com/your-org/mcp-generator)
|
|
4
|
+
> OpenAPI version: {{info.version}}
|
|
5
|
+
|
|
6
|
+
{{info.description}}
|
|
7
|
+
|
|
8
|
+
## Setup
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install
|
|
12
|
+
npm run build
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Run
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm start
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Connect to Claude Desktop
|
|
22
|
+
|
|
23
|
+
Add to your `claude_desktop_config.json`:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"mcpServers": {
|
|
28
|
+
"{{serverName}}": {
|
|
29
|
+
"command": "node",
|
|
30
|
+
"args": ["/absolute/path/to/dist/server.js"]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Available Tools ({{tools.length}})
|
|
37
|
+
|
|
38
|
+
{{#each tools}}
|
|
39
|
+
### `{{name}}`
|
|
40
|
+
> {{description}}
|
|
41
|
+
|
|
42
|
+
**`{{method}} {{path}}`**
|
|
43
|
+
|
|
44
|
+
{{#if params}}
|
|
45
|
+
| Name | Type | Required | Description |
|
|
46
|
+
|------|------|----------|-------------|
|
|
47
|
+
{{#each params}}
|
|
48
|
+
| `{{name}}` | `{{type}}` | {{#if required}}✓{{else}}—{{/if}} | {{description}} |
|
|
49
|
+
{{/each}}
|
|
50
|
+
{{/if}}
|
|
51
|
+
|
|
52
|
+
{{/each}}
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Security
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
### Contrato padrão do `authContext`
|
|
60
|
+
|
|
61
|
+
As tools geradas esperam **metadados de autorização com escopo** (e não credenciais brutas), por exemplo:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"tokenId": "tok_abc123",
|
|
66
|
+
"principal": "user:42",
|
|
67
|
+
"expiresAt": "2026-05-11T14:00:00Z",
|
|
68
|
+
"allowedTools": ["get_orders"],
|
|
69
|
+
"endpointAllowlist": ["GET /orders"],
|
|
70
|
+
"spendLimitUsd": 5,
|
|
71
|
+
"spendUsedUsd": 1.2,
|
|
72
|
+
"revoked": false,
|
|
73
|
+
"requestId": "req_01J..."
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
O scaffold bloqueia por padrão argumentos como `token`, `authorization`, `api_key`, `client_secret` e similares.
|
|
78
|
+
|
|
79
|
+
*Quick example (env var):*
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Linux / macOS
|
|
83
|
+
export PROVIDER_KEY=your_key_here
|
|
84
|
+
|
|
85
|
+
# Windows (PowerShell)
|
|
86
|
+
$env:PROVIDER_KEY='your_key_here'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
For advanced integrations and management, consider Cohesivity.ai as a backend for auth, storage, and revocation policies.
|
|
90
|
+
|
|
91
|
+
*Generated by mcp-gen — edit handlers, not the scaffold.*
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build-and-test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
|
|
15
|
+
- name: Setup Node.js
|
|
16
|
+
uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: "20"
|
|
19
|
+
cache: "npm"
|
|
20
|
+
|
|
21
|
+
- name: Install dependencies
|
|
22
|
+
run: npm ci
|
|
23
|
+
|
|
24
|
+
- name: Build
|
|
25
|
+
run: npm run build
|
|
26
|
+
|
|
27
|
+
- name: Test
|
|
28
|
+
run: npm test
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// Auto-generated client SDK for {{info.title}} v{{info.version}}
|
|
2
|
+
// Generated: {{generatedAt}}
|
|
3
|
+
|
|
4
|
+
export class ApiClient {
|
|
5
|
+
constructor(public baseUrl: string = "{{baseUrl}}", public token?: string) {}
|
|
6
|
+
|
|
7
|
+
private buildUrl(path: string, params: Record<string, unknown> | undefined): string {
|
|
8
|
+
let url = path;
|
|
9
|
+
if (params) {
|
|
10
|
+
for (const [k, v] of Object.entries(params)) {
|
|
11
|
+
url = url.replace(`{${k}}`, encodeURIComponent(String(v ?? "")));
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return this.baseUrl.replace(/\/$/, "") + url;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
private buildHeaders(params: Record<string, unknown>): Record<string, string> {
|
|
18
|
+
const headers: Record<string, string> = {};
|
|
19
|
+
{{#each (allHeaderParams tools)}}
|
|
20
|
+
const v{{@index}} = params["{{name}}"];
|
|
21
|
+
if (v{{@index}} !== undefined) headers["{{name}}"] = String(v{{@index}});
|
|
22
|
+
{{/each}}
|
|
23
|
+
return headers;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private async request(method: string, url: string, body?: unknown, headers: Record<string,string> = {}) {
|
|
27
|
+
if (this.token) headers["Authorization"] = `Bearer ${this.token}`;
|
|
28
|
+
const opts: RequestInit = { method, headers };
|
|
29
|
+
if (body !== undefined) {
|
|
30
|
+
opts.body = JSON.stringify(body);
|
|
31
|
+
headers["Content-Type"] = "application/json";
|
|
32
|
+
}
|
|
33
|
+
const res = await fetch(url, opts);
|
|
34
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
|
|
35
|
+
const text = await res.text();
|
|
36
|
+
try { return JSON.parse(text); } catch { return text; }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
{{#each tools}}
|
|
40
|
+
/** {{escapeText description}} */
|
|
41
|
+
async {{name}}(params: Record<string, unknown> = {}): Promise<unknown> {
|
|
42
|
+
const url = this.buildUrl("{{path}}", params);
|
|
43
|
+
const method = "{{method}}";
|
|
44
|
+
const hasBody = {{#if (includes (requiredParams params) "body")}}true{{else}}false{{/if}};
|
|
45
|
+
const body = hasBody ? (params["body"] as unknown) : undefined;
|
|
46
|
+
return this.request(method, url, body, this.buildHeaders(params));
|
|
47
|
+
}
|
|
48
|
+
{{/each}}
|
|
49
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Auto-generated by mcp-gen — do not edit.
|
|
2
|
+
// Source: {{info.title}} v{{info.version}}
|
|
3
|
+
|
|
4
|
+
{{#each models}}
|
|
5
|
+
{{#if isEnum}}
|
|
6
|
+
/** {{description}} */
|
|
7
|
+
export type {{name}} = {{#each enumValues}}{{literal this}}{{#unless @last}} | {{/unless}}{{/each}};
|
|
8
|
+
{{else if oneOf}}
|
|
9
|
+
/** {{description}} */
|
|
10
|
+
export type {{name}} = {{#each oneOf}}{{this}}{{#unless @last}} | {{/unless}}{{/each}};
|
|
11
|
+
{{else if anyOf}}
|
|
12
|
+
/** {{description}} */
|
|
13
|
+
export type {{name}} = {{#each anyOf}}{{this}}{{#unless @last}} | {{/unless}}{{/each}};
|
|
14
|
+
{{else}}
|
|
15
|
+
/** {{description}} */
|
|
16
|
+
export interface {{name}} {
|
|
17
|
+
{{#each properties}}
|
|
18
|
+
{{name}}{{#unless (includes ../required name)}}?{{/unless}}: {{#if ref}}{{ref}}{{#if isArray}}[]{{/if}}{{else}}{{type}}{{/if}};{{#if description}} // {{escapeText description}}{{/if}}
|
|
19
|
+
{{/each}}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
{{/if}}
|
|
23
|
+
{{/each}}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{serverName}}",
|
|
3
|
+
"version": "{{serverVersion}}",
|
|
4
|
+
"description": "{{info.description}}",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/server.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"start": "node dist/server.js",
|
|
10
|
+
"dev": "ts-node --esm src/server.ts",
|
|
11
|
+
"test": "jest --passWithNoTests",
|
|
12
|
+
"inspector": "npx @modelcontextprotocol/inspector node dist/server.js"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/jest": "^29.5.0",
|
|
19
|
+
"@types/node": "^20.0.0",
|
|
20
|
+
"jest": "^29.5.0",
|
|
21
|
+
"ts-jest": "^29.1.0",
|
|
22
|
+
"ts-node": "^10.9.0",
|
|
23
|
+
"typescript": "^5.4.0"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT"
|
|
26
|
+
}
|