@tsed/cli-mcp 7.0.0-beta.3

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.
@@ -0,0 +1,45 @@
1
+ import type { McpServer, PromptCallback } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type TokenProvider } from "@tsed/di";
3
+ export type PromptProps = Parameters<McpServer["registerPrompt"]>[1] & {
4
+ token?: TokenProvider;
5
+ name: string;
6
+ handler: PromptCallback;
7
+ };
8
+ /**
9
+ * Prompts are reusable templates that help humans prompt models to interact with your server.
10
+ * They're designed to be user-driven, and might appear as slash commands in a chat interface.
11
+ *
12
+ * ```ts
13
+ * import {definePrompt} from "@tsed/cli-mcp";
14
+ *
15
+ * export default definePrompt({
16
+ * name: "review-code",
17
+ * title: 'Code review',
18
+ * description: 'Review code for best practices and potential issues',
19
+ * argsSchema: { code: z.string() }
20
+ * handler: ({ code }) => ({
21
+ * messages: [
22
+ * {
23
+ * role: 'user',
24
+ * content: {
25
+ * type: 'text',
26
+ * text: `Please review this code:\n\n${code}`
27
+ * }
28
+ * }
29
+ * ]
30
+ * })
31
+ * });
32
+ * ```
33
+ *
34
+ * @param options {PromptProps}
35
+ */
36
+ export declare function definePrompt(options: PromptProps): import("@tsed/cli-core").FactoryTokenProvider<{
37
+ handler(...args: any[]): Promise<any>;
38
+ title?: string;
39
+ description?: string;
40
+ argsSchema?: {
41
+ [k: string]: import("zod").ZodType<string, import("zod").ZodTypeDef, string> | import("zod").ZodOptional<import("zod").ZodType<string, import("zod").ZodTypeDef, string>>;
42
+ } | undefined;
43
+ token?: TokenProvider;
44
+ name: string;
45
+ }>;
@@ -0,0 +1,46 @@
1
+ import type { ReadResourceCallback, ResourceMetadata } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type TokenProvider } from "@tsed/di";
3
+ type ResourceBaseProps = ResourceMetadata & {
4
+ token?: TokenProvider;
5
+ name: string;
6
+ };
7
+ type ResourceReadProps = ResourceBaseProps & {
8
+ uri: string;
9
+ handler: ReadResourceCallback;
10
+ };
11
+ type ResourceTemplateProps = ResourceBaseProps & {
12
+ uri: string;
13
+ handler: ReadResourceCallback;
14
+ };
15
+ export type ResourceProps = ResourceReadProps | ResourceTemplateProps;
16
+ /**
17
+ * Resources can also expose data to LLMs, but unlike tools shouldn't perform significant computation or have side effects.
18
+ *
19
+ * Resources are designed to be used in an application-driven way, meaning MCP client applications can decide how to expose them. For example, a client could expose a resource picker to the human, or could expose them to the model directly.
20
+ *
21
+ * ```ts
22
+ * import {defineResource} from "@tsed/cli-mcp";
23
+ *
24
+ * export default defineResource({
25
+ * name: "config",
26
+ * uri: "config://app",
27
+ * title: 'Application Config',
28
+ * description: 'Application configuration data',
29
+ * mimeType: 'text/plain'
30
+ * handler(uri) {
31
+ * return {
32
+ * contents: [
33
+ * {
34
+ * uri: uri.href,
35
+ * text: 'App configuration here'
36
+ * }
37
+ * ]
38
+ * }
39
+ * });
40
+ * ```
41
+ *
42
+ * @param options
43
+ */
44
+ export declare function defineResource(options: ResourceReadProps): TokenProvider;
45
+ export declare function defineResource(options: ResourceTemplateProps): TokenProvider;
46
+ export {};
@@ -0,0 +1,129 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
3
+ import type { CallToolResult, ServerNotification, ServerRequest, Tool } from "@modelcontextprotocol/sdk/types.js";
4
+ import { type TokenProvider } from "@tsed/di";
5
+ import { JsonSchema } from "@tsed/schema";
6
+ export type ToolCallback<Args = undefined> = (args: Args, extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => CallToolResult | Promise<CallToolResult>;
7
+ type ToolConfig = Parameters<McpServer["registerTool"]>[1];
8
+ export type ToolProps<Input, Output> = Omit<ToolConfig, "inputSchema" | "outputSchema"> & {
9
+ token?: TokenProvider;
10
+ name: string;
11
+ inputSchema?: JsonSchema<Input> | Tool["inputSchema"];
12
+ outputSchema?: JsonSchema<Output> | Tool["outputSchema"];
13
+ handler: ToolCallback<Input>;
14
+ };
15
+ /**
16
+ * Tools let LLMs take actions through your server. Tools can perform computation, fetch data and have side effects.
17
+ * Tools should be designed to be model-controlled - i.e. AI models will decide which tools to call, and the arguments.
18
+ *
19
+ * ```typescript
20
+ * import {defineTool} from "@tsed/cli-mcp";
21
+ * import {s} from "@tsed/schema";
22
+ *
23
+ * export default defineTool({
24
+ * name: "my-tool",
25
+ * title: "My Tool",
26
+ * description: "My tool description",
27
+ * inputSchema: s.object({
28
+ * param1: s.string().required() // also support Zod
29
+ * }),
30
+ * outputSchema: s.object({
31
+ * result: s.string().required() // also support Zod
32
+ * }),
33
+ * handler(args) {
34
+ * return {
35
+ * content: [],
36
+ * structuredContent: {
37
+ * result: "Hello World!"
38
+ * }
39
+ * }
40
+ * });
41
+ * ```
42
+ *
43
+ * @param options
44
+ */
45
+ export declare function defineTool<Input, Output = undefined>(options: ToolProps<Input, Output>): import("@tsed/cli-core").FactoryTokenProvider<{
46
+ inputSchema: Record<string, import("zod").AnyZodObject> | undefined;
47
+ outputSchema: Record<string, import("zod").AnyZodObject> | undefined;
48
+ handler(args: Input, extra: RequestHandlerExtra<ServerRequest, ServerNotification>): Promise<{
49
+ [x: string]: unknown;
50
+ content: ({
51
+ [x: string]: unknown;
52
+ type: "text";
53
+ text: string;
54
+ _meta?: {
55
+ [x: string]: unknown;
56
+ } | undefined;
57
+ } | {
58
+ [x: string]: unknown;
59
+ type: "image";
60
+ data: string;
61
+ mimeType: string;
62
+ _meta?: {
63
+ [x: string]: unknown;
64
+ } | undefined;
65
+ } | {
66
+ [x: string]: unknown;
67
+ type: "audio";
68
+ data: string;
69
+ mimeType: string;
70
+ _meta?: {
71
+ [x: string]: unknown;
72
+ } | undefined;
73
+ } | {
74
+ [x: string]: unknown;
75
+ type: "resource_link";
76
+ name: string;
77
+ uri: string;
78
+ _meta?: {
79
+ [x: string]: unknown;
80
+ } | undefined;
81
+ description?: string | undefined;
82
+ mimeType?: string | undefined;
83
+ title?: string | undefined;
84
+ icons?: {
85
+ [x: string]: unknown;
86
+ src: string;
87
+ mimeType?: string | undefined;
88
+ sizes?: string[] | undefined;
89
+ }[] | undefined;
90
+ } | {
91
+ [x: string]: unknown;
92
+ type: "resource";
93
+ resource: {
94
+ [x: string]: unknown;
95
+ text: string;
96
+ uri: string;
97
+ _meta?: {
98
+ [x: string]: unknown;
99
+ } | undefined;
100
+ mimeType?: string | undefined;
101
+ } | {
102
+ [x: string]: unknown;
103
+ uri: string;
104
+ blob: string;
105
+ _meta?: {
106
+ [x: string]: unknown;
107
+ } | undefined;
108
+ mimeType?: string | undefined;
109
+ };
110
+ _meta?: {
111
+ [x: string]: unknown;
112
+ } | undefined;
113
+ })[];
114
+ _meta?: {
115
+ [x: string]: unknown;
116
+ } | undefined;
117
+ structuredContent?: {
118
+ [x: string]: unknown;
119
+ } | undefined;
120
+ isError?: boolean | undefined;
121
+ }>;
122
+ _meta?: Record<string, unknown> | undefined;
123
+ description?: string | undefined;
124
+ title?: string | undefined;
125
+ annotations?: import("@modelcontextprotocol/sdk/types.js").ToolAnnotations | undefined;
126
+ token?: TokenProvider;
127
+ name: string;
128
+ }>;
129
+ export {};
@@ -0,0 +1,4 @@
1
+ export * from "./fn/definePrompt.js";
2
+ export * from "./fn/defineResource.js";
3
+ export * from "./fn/defineTool.js";
4
+ export * from "./services/CLIMCPServer.js";
@@ -0,0 +1,13 @@
1
+ import type { TokenProvider } from "@tsed/di";
2
+ declare global {
3
+ namespace TsED {
4
+ interface Configuration {
5
+ prompts?: TokenProvider[];
6
+ resources?: TokenProvider[];
7
+ tools?: TokenProvider[];
8
+ mcp?: {
9
+ mode: "streamable-http" | "stdio";
10
+ };
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,6 @@
1
+ import "./McpServerFactory.js";
2
+ export declare class CLIMCPServer {
3
+ protected constructor(settings: Partial<TsED.Configuration>);
4
+ static bootstrap(settings: Partial<TsED.Configuration>): Promise<void>;
5
+ bootstrap(): Promise<void>;
6
+ }
@@ -0,0 +1,6 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare const MCP_SERVER: import("@tsed/di").FactoryTokenProvider<{
3
+ server: McpServer;
4
+ connect(): Promise<void>;
5
+ }>;
6
+ export type MCP_SERVER = typeof MCP_SERVER;
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function mcpStdioServer(server: McpServer): Promise<void>;
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function mcpStreamableServer(server: McpServer): Promise<void>;
@@ -0,0 +1,2 @@
1
+ import { type AnyZodObject } from "zod";
2
+ export declare function toZod(schema: unknown): Record<string, AnyZodObject> | undefined;
package/package.json ADDED
@@ -0,0 +1,125 @@
1
+ {
2
+ "name": "@tsed/cli-mcp",
3
+ "description": "MCP CLI for Ts.ED.",
4
+ "version": "7.0.0-beta.3",
5
+ "type": "module",
6
+ "main": "./lib/esm/index.js",
7
+ "source": "./src/index.ts",
8
+ "module": "./lib/esm/index.js",
9
+ "typings": "./lib/types/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "cli-tsed-source": "./src/index.ts",
13
+ "types": "./lib/types/index.d.ts",
14
+ "import": "./lib/esm/index.js",
15
+ "default": "./lib/esm/index.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "yarn build:ts",
20
+ "build:ts": "tsc --build tsconfig.esm.json",
21
+ "test": "vitest run",
22
+ "test:ci": "vitest run --coverage.thresholds.autoUpdate=true"
23
+ },
24
+ "bin": {
25
+ "tsed": "lib/esm/bin/tsed.js",
26
+ "tsed-mcp": "lib/esm/bin/tsed-mcp.js"
27
+ },
28
+ "files": [
29
+ "lib/esm/bin/tsed.js",
30
+ "lib/esm/bin/tsed-mcp.js",
31
+ "lib/esm/bin",
32
+ "lib",
33
+ "templates"
34
+ ],
35
+ "keywords": [
36
+ "Ts.ED",
37
+ "cli",
38
+ "typescript",
39
+ "framework",
40
+ "rest",
41
+ "api",
42
+ "express",
43
+ "decorators"
44
+ ],
45
+ "engines": {
46
+ "node": ">=14"
47
+ },
48
+ "dependencies": {
49
+ "@modelcontextprotocol/sdk": "^1.19.1",
50
+ "@swc-node/register": "^1.10.9",
51
+ "@swc/core": "1.7.26",
52
+ "@swc/helpers": "^0.5.13",
53
+ "@tsed/cli-core": "7.0.0-beta.3",
54
+ "@tsed/core": ">=8.18.0",
55
+ "@tsed/di": ">=8.18.0",
56
+ "@tsed/hooks": ">=8.18.0",
57
+ "@tsed/logger": ">=8.0.3",
58
+ "@tsed/logger-std": ">=8.0.3",
59
+ "@tsed/normalize-path": ">=8.18.0",
60
+ "@tsed/openspec": ">=8.18.0",
61
+ "@tsed/schema": ">=8.18.0",
62
+ "chalk": "^5.3.0",
63
+ "change-case": "^5.4.4",
64
+ "consolidate": "^1.0.4",
65
+ "create-frame": "^1.0.0",
66
+ "fs-extra": "^11.2.0",
67
+ "globby": "^14.0.2",
68
+ "read-pkg-up": "^11.0.0",
69
+ "rxjs": "^7.8.1",
70
+ "semver": "^7.6.3",
71
+ "ts-morph": "27.0.0",
72
+ "tslib": "^2.7.0"
73
+ },
74
+ "devDependencies": {
75
+ "@tsed/typescript": "7.0.0-beta.3",
76
+ "@types/change-case": "^2.3.1",
77
+ "@types/consolidate": "0.14.4",
78
+ "cross-env": "7.0.3",
79
+ "express": "5.1.0",
80
+ "typescript": "5.6.2",
81
+ "vitest": "3.2.4"
82
+ },
83
+ "peerDependencies": {
84
+ "@tsed/core": ">=8.0.0",
85
+ "@tsed/di": ">=8.0.0",
86
+ "@tsed/hooks": ">=8.0.0",
87
+ "@tsed/logger": ">=8.0.2",
88
+ "@tsed/logger-std": ">=8.0.2",
89
+ "@tsed/openspec": ">=8.0.0",
90
+ "@tsed/schema": ">=8.0.0"
91
+ },
92
+ "peerDependenciesMeta": {
93
+ "@tsed/core": {
94
+ "optional": false
95
+ },
96
+ "@tsed/di": {
97
+ "optional": false
98
+ },
99
+ "@tsed/hooks": {
100
+ "optional": false
101
+ },
102
+ "@tsed/logger": {
103
+ "optional": false
104
+ },
105
+ "@tsed/logger-std": {
106
+ "optional": false
107
+ },
108
+ "@tsed/openspec": {
109
+ "optional": false
110
+ },
111
+ "@tsed/schema": {
112
+ "optional": false
113
+ }
114
+ },
115
+ "repository": "https://github.com/tsedio/tsed-cli",
116
+ "bugs": {
117
+ "url": "https://github.com/tsedio/tsed-cli/issues"
118
+ },
119
+ "homepage": "https://github.com/tsedio/tsed-cli/tree/master/packages/cli-mcp",
120
+ "author": "Romain Lenzotti",
121
+ "license": "MIT",
122
+ "publishConfig": {
123
+ "tag": "beta"
124
+ }
125
+ }
package/readme.md ADDED
@@ -0,0 +1,241 @@
1
+ # @tsed/cli-mcp
2
+
3
+ <p style="text-align: center" align="center">
4
+ <a href="https://tsed.dev" target="_blank"><img src="https://tsed.dev/tsed-og.png" width="200" alt="Ts.ED logo"/></a>
5
+ </p>
6
+
7
+ [![Build & Release](https://github.com/tsedio/tsed-cli/workflows/Build%20&%20Release/badge.svg?branch=master)](https://github.com/tsedio/tsed-cli/actions?query=workflow%3A%22Build+%26+Release%22)
8
+ [![npm version](https://img.shields.io/npm/v/%40tsed/cli-mcp.svg)](https://www.npmjs.com/package/@tsed/cli-mcp)
9
+ [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
10
+
11
+ > Model Context Protocol (MCP) server tooling for Ts.ED and the Ts.ED CLI.
12
+
13
+ This package provides:
14
+
15
+ - A lightweight bootstrapper to run an MCP server over stdio (`CLIMCPServer`).
16
+ - Simple helpers to declare MCP entities with Ts.ED DI context: `defineTool`, `defineResource`, and `definePrompt`.
17
+ - Utilities to bridge `@tsed/schema` and Zod for MCP schemas.
18
+
19
+ It can be used to expose Ts.ED CLI features to your AI client (e.g., Claude Desktop) or to build your own MCP server in a Ts.ED application or script.
20
+
21
+ ## Requirements
22
+
23
+ - Node.js >= 14 (per package `engines`)
24
+ - ESM module support
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ # with npm
30
+ npm i @tsed/cli-mcp
31
+ # or with yarn
32
+ yarn add @tsed/cli-mcp
33
+ # or with pnpm
34
+ pnpm add @tsed/cli-mcp
35
+ ```
36
+
37
+ ## Quick start
38
+
39
+ The fastest way to start an MCP server is to:
40
+
41
+ 1. Define one or more tools/resources/prompts with the helpers.
42
+ 2. Bootstrap the server with `CLIMCPServer.bootstrap`.
43
+
44
+ ### 1) Define a Tool
45
+
46
+ ```ts
47
+ import {defineTool} from "@tsed/cli-mcp";
48
+ import {s} from "@tsed/schema"; // or use zod directly
49
+
50
+ export const helloTool = defineTool({
51
+ name: "hello",
52
+ title: "Hello",
53
+ description: "Returns a friendly greeting",
54
+ inputSchema: s.object({name: s.string().required()}), // also supports Zod
55
+ outputSchema: s.object({message: s.string().required()}),
56
+ async handler({name}) {
57
+ return {
58
+ content: [],
59
+ structuredContent: {message: `Hello, ${name}!`}
60
+ };
61
+ }
62
+ });
63
+ ```
64
+
65
+ ### 2) Define a Resource (optional)
66
+
67
+ ```ts
68
+ import {defineResource} from "@tsed/cli-mcp";
69
+
70
+ export const configResource = defineResource({
71
+ name: "config",
72
+ uri: "config://app",
73
+ title: "Application Config",
74
+ description: "Current app configuration",
75
+ mimeType: "text/plain",
76
+ handler(uri) {
77
+ return {
78
+ contents: [
79
+ {
80
+ uri: uri.href,
81
+ text: "App configuration here"
82
+ }
83
+ ]
84
+ };
85
+ }
86
+ });
87
+ ```
88
+
89
+ ### 3) Define a Prompt (optional)
90
+
91
+ ```ts
92
+ import {definePrompt} from "@tsed/cli-mcp";
93
+ import {z} from "zod";
94
+
95
+ export const reviewPrompt = definePrompt({
96
+ name: "review-code",
97
+ title: "Code review",
98
+ description: "Review code for best practices and potential issues",
99
+ argsSchema: z.object({code: z.string()}),
100
+ handler: ({code}) => ({
101
+ messages: [
102
+ {
103
+ role: "user",
104
+ content: {type: "text", text: `Please review this code:\n\n${code}`}
105
+ }
106
+ ]
107
+ })
108
+ });
109
+ ```
110
+
111
+ ### 4) Bootstrap the MCP server (stdio)
112
+
113
+ ```ts
114
+ import {CLIMCPServer} from "@tsed/cli-mcp";
115
+ import type {TokenProvider} from "@tsed/di";
116
+ import {helloTool} from "./tools/helloTool";
117
+ import {configResource} from "./resources/configResource";
118
+ import {reviewPrompt} from "./prompts/reviewPrompt";
119
+
120
+ await CLIMCPServer.bootstrap({
121
+ name: "my-mcp-server",
122
+ version: "0.0.0",
123
+ tools: [helloTool],
124
+ resources: [configResource],
125
+ prompts: [reviewPrompt]
126
+ });
127
+ ```
128
+
129
+ The server will start over stdio using `@modelcontextprotocol/sdk`'s `StdioServerTransport`. You can then register it in any MCP-compatible client.
130
+
131
+ ## Using with Ts.ED CLI
132
+
133
+ The Ts.ED CLI ships a binary that exposes CLI features over MCP using this package. Once installed, you can run:
134
+
135
+ ```bash
136
+ npx tsed-mcp
137
+ ```
138
+
139
+ One built‑in example tool is `generate-file`, which leverages the CLI generators:
140
+
141
+ ```ts
142
+ import {defineTool} from "@tsed/cli-mcp";
143
+ import {object, string, array, number} from "@tsed/schema";
144
+ import {inject} from "@tsed/di";
145
+ import {CliProjectService} from "@tsed/cli";
146
+ import {CliTemplatesService} from "@tsed/cli";
147
+
148
+ export const generateTool = defineTool({
149
+ name: "generate-file",
150
+ title: "Generate file",
151
+ description: "Generate a new Ts.ED provider class depending on the given parameters.",
152
+ inputSchema: object({
153
+ type: string().required(),
154
+ name: string().required(),
155
+ route: string(),
156
+ directory: string(),
157
+ templateType: string(),
158
+ middlewarePosition: string()
159
+ }),
160
+ outputSchema: object({
161
+ files: array().items(string()),
162
+ count: number()
163
+ }),
164
+ async handler(args) {
165
+ const project = inject(CliProjectService);
166
+ const templates = inject(CliTemplatesService);
167
+ // map args to template options, render and transform files...
168
+ await project.createFromTemplate(args.type as any, args as any);
169
+ await project.transformFiles(args as any);
170
+ return {content: [], structuredContent: {files: templates.renderedFiles, count: templates.renderedFiles.length}};
171
+ }
172
+ });
173
+ ```
174
+
175
+ ## API Overview
176
+
177
+ - `defineTool(options)`
178
+ - Registers an MCP tool inside Ts.ED DI and ensures the handler runs inside a `DIContext`.
179
+ - Accepts `inputSchema`/`outputSchema` as `@tsed/schema` or Zod. `@tsed/schema` is automatically converted to Zod.
180
+ - `defineResource(options)`
181
+ - Registers an MCP resource (static `uri` or `template`) with a DI‑aware handler.
182
+ - `definePrompt(options)`
183
+ - Registers a reusable prompt template available to clients.
184
+ - `CLIMCPServer.bootstrap(settings)`
185
+ - Creates the Ts.ED injector, loads plugins, registers provided tools/resources/prompts, and starts MCP over stdio.
186
+
187
+ ### Schema note
188
+
189
+ This package includes a small helper to convert `@tsed/schema` to Zod at runtime so you can write your schemas once:
190
+
191
+ ```ts
192
+ import {s} from "@tsed/schema";
193
+ // under the hood we transform JsonSchema -> Zod for MCP SDK
194
+ ```
195
+
196
+ ## Configuration reference
197
+
198
+ `CLIMCPServer.bootstrap(settings: Partial<TsED.Configuration>)` supports all usual Ts.ED CLI settings plus:
199
+
200
+ - `name`: MCP server name (string)
201
+ - `version`: MCP server version (string)
202
+ - `tools`: `TokenProvider[]` returned by `defineTool`
203
+ - `resources`: `TokenProvider[]` returned by `defineResource`
204
+ - `prompts`: `TokenProvider[]` returned by `definePrompt`
205
+ - `logger.level`: log level (e.g., `info`, `debug`)
206
+
207
+ ## Contributors
208
+
209
+ Please read [contributing guidelines here](https://tsed.dev/CONTRIBUTING.html)
210
+
211
+ <a href="https://github.com/tsedio/ts-express-decorators/graphs/contributors"><img src="https://opencollective.com/tsed/contributors.svg?width=890" /></a>
212
+
213
+ ## Backers
214
+
215
+ Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/tsed#backer)]
216
+
217
+ <a href="https://opencollective.com/tsed#backers" target="_blank"><img src="https://opencollective.com/tsed/tiers/backer.svg?width=890"></a>
218
+
219
+ ## Sponsors
220
+
221
+ Support this project by becoming a sponsor. Your logo will show up here with a link to your
222
+ website. [[Become a sponsor](https://opencollective.com/tsed#sponsor)]
223
+
224
+ ## License
225
+
226
+ The MIT License (MIT)
227
+
228
+ Copyright (c) 2016 - Today Romain Lenzotti
229
+
230
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
231
+ documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
232
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
233
+ persons to whom the Software is furnished to do so, subject to the following conditions:
234
+
235
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
236
+ Software.
237
+
238
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
239
+ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
240
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
241
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.