mcp-ts-template 2.9.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +126 -160
- package/dist/index.js +154359 -180487
- package/package.json +43 -44
package/README.md
CHANGED
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<h1>mcp-ts-template</h1>
|
|
3
|
-
<p><b>TypeScript template for building Model Context Protocol (MCP) servers. Ships with declarative tools/resources, pluggable auth, multi-backend storage, OpenTelemetry observability, and
|
|
3
|
+
<p><b>TypeScript template for building Model Context Protocol (MCP) servers. Ships with declarative tools/resources, pluggable auth, multi-backend storage, OpenTelemetry observability, and support for both local and edge (Cloudflare Workers) runtimes.</b>
|
|
4
4
|
<div>7 Tools • 2 Resources • 1 Prompt</div>
|
|
5
5
|
</p>
|
|
6
6
|
</div>
|
|
7
7
|
|
|
8
8
|
<div align="center">
|
|
9
9
|
|
|
10
|
-
[](./CHANGELOG.md) [](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-11-25/changelog.mdx) [](https://modelcontextprotocol.io/) [](./LICENSE)
|
|
11
|
+
|
|
12
|
+
[](https://github.com/cyanheads/mcp-ts-template/issues) [](https://www.typescriptlang.org/) [](https://bun.sh/) [](./coverage/index.html)
|
|
11
13
|
|
|
12
14
|
</div>
|
|
13
15
|
|
|
14
16
|
---
|
|
15
17
|
|
|
16
|
-
##
|
|
18
|
+
## Features
|
|
17
19
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
- **Edge-Ready**: Write code once and run it seamlessly on your local machine or at the edge on Cloudflare Workers.
|
|
20
|
+
- Define tools and resources in single, self-contained files. The framework handles registration.
|
|
21
|
+
- Tools can prompt users for missing parameters mid-execution via elicitation.
|
|
22
|
+
- Unified `McpError` system for consistent, structured error responses.
|
|
23
|
+
- Auth modes: `none`, `jwt`, or `oauth`. Wrap logic with `withToolAuth`/`withResourceAuth`.
|
|
24
|
+
- Swap storage backends (`in-memory`, `filesystem`, `Supabase`, `Cloudflare D1/KV/R2`) without changing tool logic. Includes cursor pagination, batch ops, and input validation.
|
|
25
|
+
- Structured logging (Pino) with optional OpenTelemetry for tracing and metrics.
|
|
26
|
+
- Custom typed DI container with `Token<T>` phantom branding. No external deps.
|
|
27
|
+
- Pluggable service integrations: LLM (OpenRouter), TTS (ElevenLabs).
|
|
28
|
+
- Parsing helpers (PDF, YAML, CSV, frontmatter), formatting (diffs, tables, trees, markdown), scheduling, security.
|
|
29
|
+
- Runs on local (stdio/HTTP) and edge (Cloudflare Workers) with the same code.
|
|
29
30
|
|
|
30
|
-
##
|
|
31
|
+
## Architecture
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
Modular, domain-driven layout with clear separation of concerns:
|
|
33
34
|
|
|
34
35
|
```
|
|
35
36
|
┌─────────────────────────────────────────────────────────┐
|
|
@@ -39,36 +40,34 @@ This template follows a modular, domain-driven architecture with clear separatio
|
|
|
39
40
|
▼
|
|
40
41
|
┌─────────────────────────────────────────────────────────┐
|
|
41
42
|
│ MCP Server (Tools, Resources) │
|
|
42
|
-
│
|
|
43
|
+
│ [MCP Server Guide](src/mcp-server/) │
|
|
43
44
|
└────────────────────┬────────────────────────────────────┘
|
|
44
45
|
│ Dependency Injection
|
|
45
46
|
▼
|
|
46
47
|
┌─────────────────────────────────────────────────────────┐
|
|
47
48
|
│ Dependency Injection Container │
|
|
48
|
-
│
|
|
49
|
+
│ [Container Guide](src/container/) │
|
|
49
50
|
└────────────────────┬────────────────────────────────────┘
|
|
50
51
|
│
|
|
51
52
|
┌────────────┼────────────┐
|
|
52
53
|
▼ ▼ ▼
|
|
53
54
|
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
54
55
|
│ Services │ │ Storage │ │ Utilities│
|
|
55
|
-
│
|
|
56
|
+
│ [→] │ │ [→] │ │ [→] │
|
|
56
57
|
└──────────┘ └──────────┘ └──────────┘
|
|
57
58
|
|
|
58
59
|
[→]: src/services/ [→]: src/storage/ [→]: src/utils/
|
|
59
60
|
```
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
- **[MCP Server](src/mcp-server/)** - Tools, resources, prompts, and transport layer implementations
|
|
64
|
-
- **[Container](src/container/)** - Typed dependency injection container with zero external dependencies
|
|
65
|
-
- **[Services](src/services/)** - External service integrations (LLM, Speech, Graph) with pluggable providers
|
|
66
|
-
- **[Storage](src/storage/)** - Abstracted persistence layer with multiple backend support
|
|
67
|
-
- **[Utilities](src/utils/)** - Cross-cutting concerns (logging, security, parsing, telemetry)
|
|
62
|
+
Key modules:
|
|
68
63
|
|
|
69
|
-
|
|
64
|
+
- [MCP Server](src/mcp-server/) — Tools, resources, prompts, and transport layer
|
|
65
|
+
- [Container](src/container/) — Typed DI container, no external deps
|
|
66
|
+
- [Services](src/services/) — External integrations (LLM, Speech, Graph) with pluggable providers
|
|
67
|
+
- [Storage](src/storage/) — Persistence layer with multiple backend support
|
|
68
|
+
- [Utilities](src/utils/) — Logging, security, parsing, telemetry
|
|
70
69
|
|
|
71
|
-
##
|
|
70
|
+
## Included capabilities
|
|
72
71
|
|
|
73
72
|
This template includes working examples to get you started.
|
|
74
73
|
|
|
@@ -97,11 +96,11 @@ This template includes working examples to get you started.
|
|
|
97
96
|
| :---------------- | :--------------------------------------------------------------- |
|
|
98
97
|
| **`code-review`** | A structured prompt for guiding an LLM to perform a code review. |
|
|
99
98
|
|
|
100
|
-
##
|
|
99
|
+
## Getting started
|
|
101
100
|
|
|
102
|
-
### MCP
|
|
101
|
+
### MCP client configuration
|
|
103
102
|
|
|
104
|
-
Add the following to your MCP
|
|
103
|
+
Add the following to your MCP client configuration file.
|
|
105
104
|
|
|
106
105
|
```json
|
|
107
106
|
{
|
|
@@ -123,7 +122,7 @@ Add the following to your MCP Client configuration file (e.g., `cline_mcp_settin
|
|
|
123
122
|
|
|
124
123
|
### Prerequisites
|
|
125
124
|
|
|
126
|
-
- [Bun v1.2.
|
|
125
|
+
- [Bun v1.2.0](https://bun.sh/) or higher.
|
|
127
126
|
|
|
128
127
|
### Installation
|
|
129
128
|
|
|
@@ -145,183 +144,150 @@ cd mcp-ts-template
|
|
|
145
144
|
bun install
|
|
146
145
|
```
|
|
147
146
|
|
|
148
|
-
##
|
|
147
|
+
## Configuration
|
|
149
148
|
|
|
150
149
|
All configuration is centralized and validated at startup in `src/config/index.ts`. Key environment variables in your `.env` file include:
|
|
151
150
|
|
|
152
|
-
| Variable
|
|
153
|
-
|
|
|
154
|
-
| `MCP_TRANSPORT_TYPE`
|
|
155
|
-
| `MCP_HTTP_PORT`
|
|
156
|
-
| `MCP_HTTP_HOST`
|
|
157
|
-
| `
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
160
|
-
| `
|
|
161
|
-
| `
|
|
162
|
-
| `
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
166
|
-
| `
|
|
167
|
-
| `
|
|
168
|
-
| `
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
- **Modes**: `none` (default), `jwt` (requires `MCP_AUTH_SECRET_KEY`), or `oauth` (requires `OAUTH_ISSUER_URL` and `OAUTH_AUDIENCE`).
|
|
176
|
-
- **Enforcement**: Wrap your tool/resource `logic` functions with `withToolAuth([...])` or `withResourceAuth([...])` to enforce scope checks. Scope checks are bypassed for developer convenience when auth mode is `none`.
|
|
151
|
+
| Variable | Description | Default |
|
|
152
|
+
| :------------------------ | :--------------------------------------------------------------------------------------------------------- | :----------- |
|
|
153
|
+
| `MCP_TRANSPORT_TYPE` | The transport to use: `stdio` or `http`. | `stdio` |
|
|
154
|
+
| `MCP_HTTP_PORT` | The port for the HTTP server. | `3010` |
|
|
155
|
+
| `MCP_HTTP_HOST` | The hostname for the HTTP server. | `127.0.0.1` |
|
|
156
|
+
| `MCP_LOG_LEVEL` | Logging level (`debug`, `info`, `notice`, `warning`, `error`, `crit`, `alert`, `emerg`). | `debug` |
|
|
157
|
+
| `MCP_AUTH_MODE` | Authentication mode: `none`, `jwt`, or `oauth`. | `none` |
|
|
158
|
+
| `MCP_AUTH_SECRET_KEY` | **Required for `jwt` auth mode.** A 32+ character secret. | `(none)` |
|
|
159
|
+
| `DEV_MCP_AUTH_BYPASS` | Set to `true` to bypass JWT auth in development (requires no secret key). | `false` |
|
|
160
|
+
| `OAUTH_ISSUER_URL` | **Required for `oauth` auth mode.** URL of the OIDC provider. | `(none)` |
|
|
161
|
+
| `OAUTH_AUDIENCE` | **Required for `oauth` auth mode.** Expected audience claim in the JWT. | `(none)` |
|
|
162
|
+
| `STORAGE_PROVIDER_TYPE` | Storage backend: `in-memory`, `filesystem`, `supabase`, `cloudflare-d1`, `cloudflare-kv`, `cloudflare-r2`. | `in-memory` |
|
|
163
|
+
| `STORAGE_FILESYSTEM_PATH` | Path to the storage directory (for `filesystem` provider). | `./.storage` |
|
|
164
|
+
| `SUPABASE_URL` | **Required for `supabase` storage.** Your Supabase project URL. | `(none)` |
|
|
165
|
+
| `SUPABASE_ANON_KEY` | **Required for `supabase` storage.** Your Supabase anon key. | `(none)` |
|
|
166
|
+
| `OTEL_ENABLED` | Set to `true` to enable OpenTelemetry. | `false` |
|
|
167
|
+
| `OPENROUTER_API_KEY` | API key for OpenRouter LLM service. | `(none)` |
|
|
168
|
+
|
|
169
|
+
### Authentication and authorization
|
|
170
|
+
|
|
171
|
+
- Modes: `none` (default), `jwt` (requires `MCP_AUTH_SECRET_KEY`), or `oauth` (requires `OAUTH_ISSUER_URL` and `OAUTH_AUDIENCE`).
|
|
172
|
+
- In development, set `DEV_MCP_AUTH_BYPASS=true` to skip JWT validation without a secret key. Rejected in production.
|
|
173
|
+
- Wrap tool/resource `logic` with `withToolAuth([...])` or `withResourceAuth([...])` for scope checks. Checks are bypassed when auth mode is `none`.
|
|
177
174
|
|
|
178
175
|
### Storage
|
|
179
176
|
|
|
180
|
-
-
|
|
181
|
-
-
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
- **Advanced Features**:
|
|
185
|
-
- **Secure Pagination**: Opaque cursors with tenant ID binding prevent cross-tenant attacks
|
|
186
|
-
- **Batch Operations**: Parallel execution for `getMany()`, `setMany()`, `deleteMany()`
|
|
187
|
-
- **TTL Support**: Time-to-live with proper expiration handling across all providers
|
|
188
|
-
- **Comprehensive Validation**: Centralized input validation for tenant IDs, keys, and options
|
|
177
|
+
- DI-managed `StorageService` provides a consistent API for persistence. Never access `fs` or storage SDKs directly from tool logic.
|
|
178
|
+
- Default provider is `in-memory`. Node-only: `filesystem`. Edge-compatible: `supabase`, `cloudflare-kv`, `cloudflare-r2`.
|
|
179
|
+
- `StorageService` requires `context.tenantId`, auto-propagated from the JWT `tid` claim when auth is enabled.
|
|
180
|
+
- Opaque cursor pagination with tenant binding, parallel batch ops (`getMany`/`setMany`/`deleteMany`), TTL support, centralized input validation.
|
|
189
181
|
|
|
190
182
|
### Observability
|
|
191
183
|
|
|
192
|
-
-
|
|
193
|
-
-
|
|
184
|
+
- Pino for structured JSON logging. All logs include `RequestContext`.
|
|
185
|
+
- OpenTelemetry disabled by default. Enable with `OTEL_ENABLED=true`. HTTP spans via `@hono/otel` (works on Bun). Tool-call metrics (duration, payload sizes, errors) captured automatically. Pino logs correlate to traces via `trace_id`/`span_id`.
|
|
194
186
|
|
|
195
|
-
##
|
|
187
|
+
## Running the server
|
|
196
188
|
|
|
197
|
-
### Local
|
|
189
|
+
### Local development
|
|
198
190
|
|
|
199
191
|
- **Build and run the production version**:
|
|
200
192
|
|
|
201
193
|
```sh
|
|
202
194
|
# One-time build
|
|
203
|
-
bun rebuild
|
|
195
|
+
bun run rebuild
|
|
204
196
|
|
|
205
197
|
# Run the built server
|
|
206
|
-
bun start:http
|
|
198
|
+
bun run start:http
|
|
207
199
|
# or
|
|
208
|
-
bun start:stdio
|
|
200
|
+
bun run start:stdio
|
|
209
201
|
```
|
|
210
202
|
|
|
211
203
|
- **Run checks and tests**:
|
|
212
204
|
```sh
|
|
213
|
-
bun devcheck # Lints, formats, type-checks, and more
|
|
205
|
+
bun run devcheck # Lints, formats, type-checks, and more
|
|
214
206
|
bun run test # Runs the test suite (Do not use 'bun test' directly as it may not work correctly)
|
|
215
207
|
```
|
|
216
208
|
|
|
217
|
-
### Cloudflare
|
|
209
|
+
### Cloudflare workers
|
|
218
210
|
|
|
219
211
|
1. **Build the Worker bundle**:
|
|
220
212
|
|
|
221
213
|
```sh
|
|
222
|
-
bun build:worker
|
|
214
|
+
bun run build:worker
|
|
223
215
|
```
|
|
224
216
|
|
|
225
217
|
2. **Run locally with Wrangler**:
|
|
226
218
|
|
|
227
219
|
```sh
|
|
228
|
-
bun deploy:dev
|
|
220
|
+
bun run deploy:dev
|
|
229
221
|
```
|
|
230
222
|
|
|
231
223
|
3. **Deploy to Cloudflare**:
|
|
232
224
|
|
|
233
225
|
```sh
|
|
234
|
-
bun deploy:prod
|
|
226
|
+
bun run deploy:prod
|
|
235
227
|
```
|
|
236
228
|
|
|
237
229
|
> **Note**: The `wrangler.toml` file is pre-configured to enable `nodejs_compat` for best results.
|
|
238
230
|
|
|
239
|
-
##
|
|
240
|
-
|
|
241
|
-
| Directory
|
|
242
|
-
|
|
|
243
|
-
| `src/mcp-server/tools/definitions`
|
|
244
|
-
| `src/mcp-server/resources/definitions`
|
|
245
|
-
| `src/mcp-server/
|
|
246
|
-
| `src/
|
|
247
|
-
| `src/
|
|
248
|
-
| `src/
|
|
249
|
-
| `src/
|
|
250
|
-
| `src/
|
|
251
|
-
| `
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
- **[docs/tree.md](docs/tree.md)** - Complete visual directory structure
|
|
293
|
-
- **[docs/publishing-mcp-server-registry.md](docs/publishing-mcp-server-registry.md)** - Publishing guide for MCP Registry
|
|
294
|
-
|
|
295
|
-
## 🧑💻 Agent Development Guide
|
|
296
|
-
|
|
297
|
-
For a strict set of rules when using this template with an AI agent, please refer to **`AGENTS.md`**. Key principles include:
|
|
298
|
-
|
|
299
|
-
- **Logic Throws, Handlers Catch**: Never use `try/catch` in your tool/resource `logic`. Throw an `McpError` instead.
|
|
300
|
-
- **Use Elicitation for Missing Input**: If a tool requires user input that wasn't provided, use the `elicitInput` function from the `SdkContext` to ask the user for it.
|
|
301
|
-
- **Pass the Context**: Always pass the `RequestContext` object through your call stack.
|
|
302
|
-
- **Use the Barrel Exports**: Register new tools and resources only in the `index.ts` barrel files.
|
|
303
|
-
|
|
304
|
-
## ❓ FAQ
|
|
305
|
-
|
|
306
|
-
- **Does this work with both STDIO and Streamable HTTP?**
|
|
307
|
-
- Yes. Both transports are first-class citizens. Use `bun run dev:stdio` or `bun run dev:http`.
|
|
308
|
-
- **Can I deploy this to the edge?**
|
|
309
|
-
- Yes. The template is designed for Cloudflare Workers. Run `bun run build:worker` and deploy with Wrangler.
|
|
310
|
-
- **Do I have to use OpenTelemetry?**
|
|
311
|
-
- No, it is disabled by default. Enable it by setting `OTEL_ENABLED=true` in your `.env` file.
|
|
312
|
-
- **How do I publish my server to the MCP Registry?**
|
|
313
|
-
- Follow the step-by-step guide in `docs/publishing-mcp-server-registry.md`.
|
|
314
|
-
|
|
315
|
-
## 🤝 Contributing
|
|
316
|
-
|
|
317
|
-
Issues and pull requests are welcome! If you plan to contribute, please run the local checks and tests before submitting your PR.
|
|
231
|
+
## Project structure
|
|
232
|
+
|
|
233
|
+
| Directory | Purpose & Contents | Guide |
|
|
234
|
+
| :-------------------------------------- | :----------------------------------------------------------------------------------- | :----------------------------------- |
|
|
235
|
+
| `src/mcp-server/tools/definitions` | Tool definitions (`*.tool.ts`). Add new capabilities here. | [MCP Guide](src/mcp-server/) |
|
|
236
|
+
| `src/mcp-server/resources/definitions` | Resource definitions (`*.resource.ts`). Add new data sources here. | [MCP Guide](src/mcp-server/) |
|
|
237
|
+
| `src/mcp-server/prompts/definitions` | Prompt definitions (`*.prompt.ts`). Add new prompt templates here. | [MCP Guide](src/mcp-server/) |
|
|
238
|
+
| `src/mcp-server/tasks` | Async task infrastructure (MCP Tasks API, experimental). | [MCP Guide](src/mcp-server/) |
|
|
239
|
+
| `src/mcp-server/transports` | HTTP and STDIO transports, including auth middleware. | [MCP Guide](src/mcp-server/) |
|
|
240
|
+
| `src/storage` | `StorageService` abstraction and provider implementations. | [Storage Guide](src/storage/) |
|
|
241
|
+
| `src/services` | External service integrations (LLM, Speech, Graph) with pluggable providers. | [Services Guide](src/services/) |
|
|
242
|
+
| `src/container` | DI container registrations and tokens. | [Container Guide](src/container/) |
|
|
243
|
+
| `src/utils` | Core utilities for logging, error handling, performance, security, and telemetry. | |
|
|
244
|
+
| `src/config` | Environment variable parsing and validation with Zod. | |
|
|
245
|
+
| `tests/` | Unit and integration tests, mirroring the `src/` directory structure. | |
|
|
246
|
+
|
|
247
|
+
## Documentation
|
|
248
|
+
|
|
249
|
+
Each module directory has its own README with architecture details and examples.
|
|
250
|
+
|
|
251
|
+
### Core modules
|
|
252
|
+
|
|
253
|
+
- [MCP Server Guide](src/mcp-server/) — Building tools, resources, auth, transports, SDK context, response formatting
|
|
254
|
+
- [Container Guide](src/container/) — DI tokens, registration, service lifetimes, testing with mocks
|
|
255
|
+
- [Services Guide](src/services/) — LLM (OpenRouter), Speech (ElevenLabs, Whisper), Graph, custom providers
|
|
256
|
+
- [Storage Guide](src/storage/) — Provider implementations, multi-tenancy, pagination, batch ops, TTL
|
|
257
|
+
|
|
258
|
+
### Other references
|
|
259
|
+
|
|
260
|
+
- [AGENTS.md](AGENTS.md) — Development rules for AI agents
|
|
261
|
+
- [CHANGELOG.md](CHANGELOG.md) — Version history and breaking changes
|
|
262
|
+
- [docs/tree.md](docs/tree.md) — Visual directory structure
|
|
263
|
+
- [docs/publishing-mcp-server-registry.md](docs/publishing-mcp-server-registry.md) — Publishing to MCP Registry
|
|
264
|
+
|
|
265
|
+
## Agent development guide
|
|
266
|
+
|
|
267
|
+
See `AGENTS.md` for the full rules when using this template with an AI agent. Key principles:
|
|
268
|
+
|
|
269
|
+
- Never use `try/catch` in tool/resource `logic`. Throw `McpError` instead — handlers catch.
|
|
270
|
+
- Use `elicitInput` from `SdkContext` to ask for missing user input.
|
|
271
|
+
- Pass `RequestContext` through the call stack.
|
|
272
|
+
- Import from the defining file, not barrel `index.ts`. Register new tools/resources in `definitions/index.ts`.
|
|
273
|
+
|
|
274
|
+
## FAQ
|
|
275
|
+
|
|
276
|
+
- **Does this work with both STDIO and Streamable HTTP?** Yes. Use `bun run dev:stdio` or `bun run dev:http`.
|
|
277
|
+
- **Can I deploy this to the edge?** Yes. Run `bun run build:worker` and deploy with Wrangler.
|
|
278
|
+
- **Do I have to use OpenTelemetry?** No, disabled by default. Set `OTEL_ENABLED=true` to enable.
|
|
279
|
+
- **How do I publish my server to the MCP Registry?** See `docs/publishing-mcp-server-registry.md`.
|
|
280
|
+
|
|
281
|
+
## Contributing
|
|
282
|
+
|
|
283
|
+
Issues and pull requests are welcome. Run checks and tests before submitting:
|
|
318
284
|
|
|
319
285
|
```sh
|
|
320
286
|
bun run devcheck
|
|
321
|
-
bun test
|
|
287
|
+
bun run test
|
|
322
288
|
```
|
|
323
289
|
|
|
324
|
-
##
|
|
290
|
+
## License
|
|
325
291
|
|
|
326
292
|
This project is licensed under the Apache 2.0 License. See the [LICENSE](./LICENSE) file for details.
|
|
327
293
|
|