@o3r/mcp 0.0.0-placeholder
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 +26 -0
- package/README.md +36 -0
- package/cli/index.d.ts +2 -0
- package/cli/index.d.ts.map +1 -0
- package/cli/index.js +13 -0
- package/cli/index.js.map +1 -0
- package/mcp-server.d.ts +6 -0
- package/mcp-server.d.ts.map +1 -0
- package/mcp-server.js +40 -0
- package/mcp-server.js.map +1 -0
- package/package.json +147 -0
- package/resources/instructions/best-practices.md +52 -0
- package/tools/best-practices.d.ts +7 -0
- package/tools/best-practices.d.ts.map +1 -0
- package/tools/best-practices.js +37 -0
- package/tools/best-practices.js.map +1 -0
- package/tools/create-monorepo-with-app.d.ts +7 -0
- package/tools/create-monorepo-with-app.d.ts.map +1 -0
- package/tools/create-monorepo-with-app.js +32 -0
- package/tools/create-monorepo-with-app.js.map +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Copyright Amadeus SAS
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
4
|
+
are permitted provided that the following conditions are met:
|
|
5
|
+
|
|
6
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
7
|
+
list of conditions and the following disclaimer.
|
|
8
|
+
|
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
10
|
+
this list of conditions and the following disclaimer in the documentation and/or
|
|
11
|
+
other materials provided with the distribution.
|
|
12
|
+
|
|
13
|
+
3. Neither the name of the copyright holder nor the names of its contributors
|
|
14
|
+
may be used to endorse or promote products derived from this software without
|
|
15
|
+
specific prior written permission.
|
|
16
|
+
|
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
18
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
19
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
21
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
22
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
23
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
24
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
25
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
26
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<h1 align="center">Otter MCP</h1>
|
|
2
|
+
<p align="center">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/AmadeusITGroup/otter/main/assets/logo/otter.png" alt="Super cute Otter!" width="40%"/>
|
|
4
|
+
</p>
|
|
5
|
+
|
|
6
|
+
<br />
|
|
7
|
+
<br />
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
|
|
11
|
+
A small example of an MCP server.
|
|
12
|
+
|
|
13
|
+
## How to use with VSCode
|
|
14
|
+
|
|
15
|
+
To add the Otter MCP server, you should first activate mcp with `"chat.mcp.enabled": true`.
|
|
16
|
+
|
|
17
|
+
> [!WARNING]
|
|
18
|
+
> If you are logged into VSCode with your company account,
|
|
19
|
+
> this setting may be grayed out. This may be due to your company's setting.
|
|
20
|
+
|
|
21
|
+
Then, in your `.vscode/mcp.json` add
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"Otter": {
|
|
25
|
+
"type": "stdio",
|
|
26
|
+
"command": "npx",
|
|
27
|
+
"args": ["-y", "-p", "@o3r/mcp", "o3r-mcp-start"]
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
> [!NOTE]
|
|
33
|
+
> If you want to test the MCP server locally while you are working on it,
|
|
34
|
+
> you need to build it first with the command:
|
|
35
|
+
> - `yarn nx build mcp`
|
|
36
|
+
|
package/cli/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
package/cli/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const stdio_1 = require("@modelcontextprotocol/sdk/server/stdio");
|
|
4
|
+
const mcp_server_1 = require("../mcp-server");
|
|
5
|
+
async function startMcpServer() {
|
|
6
|
+
const server = await (0, mcp_server_1.createMcpServer)();
|
|
7
|
+
const transport = new stdio_1.StdioServerTransport();
|
|
8
|
+
await server.connect(transport);
|
|
9
|
+
// Logging as error as recommended by modelcontextprotocol.io (https://modelcontextprotocol.io/quickstart/server#quick-examples-2)
|
|
10
|
+
console.error('Server connected...');
|
|
11
|
+
}
|
|
12
|
+
void startMcpServer();
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
package/cli/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;AAAA,kEAEgD;AAChD,8CAEuB;AAEvB,KAAK,UAAU,cAAc;IAC3B,MAAM,MAAM,GAAG,MAAM,IAAA,4BAAe,GAAE,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,4BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,kIAAkI;IAClI,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;AACvC,CAAC;AAED,KAAK,cAAc,EAAE,CAAC"}
|
package/mcp-server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,SAAS,EACV,MAAM,yCAAyC,CAAC;AAQjD;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,SAAS,CAAC,CAyC1D"}
|
package/mcp-server.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMcpServer = createMcpServer;
|
|
4
|
+
const promises_1 = require("node:fs/promises");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
7
|
+
const best_practices_1 = require("./tools/best-practices");
|
|
8
|
+
const create_monorepo_with_app_1 = require("./tools/create-monorepo-with-app");
|
|
9
|
+
/**
|
|
10
|
+
* Create an MCP server instance.
|
|
11
|
+
*/
|
|
12
|
+
async function createMcpServer() {
|
|
13
|
+
const { name, version } = JSON.parse(await (0, promises_1.readFile)((0, node_path_1.join)(__dirname, '..', 'package.json'), 'utf8'));
|
|
14
|
+
const server = new mcp_js_1.McpServer({
|
|
15
|
+
name,
|
|
16
|
+
version,
|
|
17
|
+
capabilities: {
|
|
18
|
+
resources: {},
|
|
19
|
+
tools: {}
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
server.registerResource('instructions', 'instructions://best-practices', {
|
|
23
|
+
title: 'Otter Best Practices and Code Generation Guide',
|
|
24
|
+
description: "A comprehensive guide detailing Otter's best practices for code generation and development."
|
|
25
|
+
+ ' This guide should be used as a reference by an LLM to ensure any generated code'
|
|
26
|
+
+ ' adheres to modern Otter and Angular standards.',
|
|
27
|
+
mimeType: 'text/markdown'
|
|
28
|
+
}, async () => {
|
|
29
|
+
// Logging as error as recommended by modelcontextprotocol.io (https://modelcontextprotocol.io/quickstart/server#quick-examples-2)
|
|
30
|
+
console.error('Fetching best practices guide...');
|
|
31
|
+
const text = await (0, promises_1.readFile)((0, node_path_1.join)(__dirname, 'resources', 'instructions', 'best-practices.md'), 'utf8');
|
|
32
|
+
// Logging as error as recommended by modelcontextprotocol.io (https://modelcontextprotocol.io/quickstart/server#quick-examples-2)
|
|
33
|
+
console.error('Best practices guide fetched successfully.');
|
|
34
|
+
return { contents: [{ uri: 'instructions://best-practices', text }] };
|
|
35
|
+
});
|
|
36
|
+
(0, best_practices_1.registerBestPracticesTool)(server);
|
|
37
|
+
(0, create_monorepo_with_app_1.registerCreateMonorepoWithAppTool)(server);
|
|
38
|
+
return server;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":";;AAmBA,0CAyCC;AA5DD,+CAE0B;AAC1B,yCAEmB;AACnB,oEAEiD;AACjD,2DAEgC;AAChC,+EAE0C;AAE1C;;GAEG;AACI,KAAK,UAAU,eAAe;IACnC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,IAAA,mBAAQ,EAAC,IAAA,gBAAI,EAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAsC,CAAC;IACzI,MAAM,MAAM,GAAG,IAAI,kBAAS,CAAC;QAC3B,IAAI;QACJ,OAAO;QACP,YAAY,EAAE;YACZ,SAAS,EAAE,EAAE;YACb,KAAK,EAAE,EAAE;SACV;KACF,CAAC,CAAC;IAEH,MAAM,CAAC,gBAAgB,CACrB,cAAc,EACd,+BAA+B,EAC/B;QACE,KAAK,EAAE,gDAAgD;QACvD,WAAW,EACT,6FAA6F;cAC3F,kFAAkF;cAClF,iDAAiD;QACrD,QAAQ,EAAE,eAAe;KAC1B,EACD,KAAK,IAAI,EAAE;QACT,kIAAkI;QAClI,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,MAAM,IAAA,mBAAQ,EACzB,IAAA,gBAAI,EAAC,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,mBAAmB,CAAC,EACjE,MAAM,CACP,CAAC;QACF,kIAAkI;QAClI,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAE5D,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,+BAA+B,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACxE,CAAC,CACF,CAAC;IAEF,IAAA,0CAAyB,EAAC,MAAM,CAAC,CAAC;IAElC,IAAA,4DAAiC,EAAC,MAAM,CAAC,CAAC;IAE1C,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@o3r/mcp",
|
|
3
|
+
"version": "0.0.0-placeholder",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "This module provides a MCP Server",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"mcp",
|
|
10
|
+
"otter",
|
|
11
|
+
"otter-module"
|
|
12
|
+
],
|
|
13
|
+
"bin": {
|
|
14
|
+
"o3r-mcp-start": "./cli/index.js"
|
|
15
|
+
},
|
|
16
|
+
"main": "./cli/index.js",
|
|
17
|
+
"scripts": {
|
|
18
|
+
"nx": "nx",
|
|
19
|
+
"ng": "yarn nx",
|
|
20
|
+
"build": "yarn nx build mcp",
|
|
21
|
+
"compile": "tsc -b ./tsconfig.build.json && yarn cpy 'src/resources/**/*.md' dist/resources && yarn cpy package.json dist && patch-package-json-main"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@modelcontextprotocol/sdk": "~1.17.0",
|
|
25
|
+
"tslib": "^2.6.2",
|
|
26
|
+
"zod": "~3.25.76"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@angular/common": "~19.2.0",
|
|
30
|
+
"@angular/compiler": "~19.2.0",
|
|
31
|
+
"@angular/compiler-cli": "~19.2.0",
|
|
32
|
+
"@angular/core": "~19.2.0",
|
|
33
|
+
"@angular/platform-browser": "~19.2.0",
|
|
34
|
+
"@angular/platform-browser-dynamic": "~19.2.0",
|
|
35
|
+
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
|
|
36
|
+
"@nx/eslint": "~20.8.0",
|
|
37
|
+
"@nx/eslint-plugin": "~20.8.0",
|
|
38
|
+
"@nx/jest": "~20.8.0",
|
|
39
|
+
"@nx/js": "~20.8.0",
|
|
40
|
+
"@o3r/build-helpers": "workspace:^",
|
|
41
|
+
"@o3r/eslint-config": "workspace:^",
|
|
42
|
+
"@o3r/eslint-plugin": "workspace:^",
|
|
43
|
+
"@o3r/test-helpers": "workspace:^",
|
|
44
|
+
"@stylistic/eslint-plugin": "~3.1.0",
|
|
45
|
+
"@types/jest": "~29.5.2",
|
|
46
|
+
"@types/node": "^20.0.0",
|
|
47
|
+
"@typescript-eslint/parser": "~8.37.0",
|
|
48
|
+
"angular-eslint": "~19.4.0",
|
|
49
|
+
"cpy-cli": "^5.0.0",
|
|
50
|
+
"eslint": "~9.31.0",
|
|
51
|
+
"eslint-import-resolver-node": "~0.3.9",
|
|
52
|
+
"eslint-import-resolver-typescript": "~3.10.0",
|
|
53
|
+
"eslint-plugin-import": "~2.32.0",
|
|
54
|
+
"eslint-plugin-import-newlines": "~1.4.0",
|
|
55
|
+
"eslint-plugin-jest": "~28.14.0",
|
|
56
|
+
"eslint-plugin-jsdoc": "~50.8.0",
|
|
57
|
+
"eslint-plugin-prefer-arrow": "~1.2.3",
|
|
58
|
+
"eslint-plugin-unicorn": "~56.0.0",
|
|
59
|
+
"eslint-plugin-unused-imports": "~4.1.4",
|
|
60
|
+
"globals": "^15.9.0",
|
|
61
|
+
"jest": "~29.7.0",
|
|
62
|
+
"jest-environment-jsdom": "~29.7.0",
|
|
63
|
+
"jest-junit": "~16.0.0",
|
|
64
|
+
"jest-preset-angular": "~14.5.0",
|
|
65
|
+
"jsonc-eslint-parser": "~2.4.0",
|
|
66
|
+
"nx": "~20.8.0",
|
|
67
|
+
"rxjs": "^7.8.1",
|
|
68
|
+
"ts-jest": "~29.3.0",
|
|
69
|
+
"ts-node": "~10.9.2",
|
|
70
|
+
"type-fest": "^4.30.1",
|
|
71
|
+
"typescript": "~5.8.2",
|
|
72
|
+
"typescript-eslint": "~8.37.0",
|
|
73
|
+
"zone.js": "~0.15.0"
|
|
74
|
+
},
|
|
75
|
+
"engines": {
|
|
76
|
+
"node": "^20.11.1 || >=22.0.0"
|
|
77
|
+
},
|
|
78
|
+
"contributors": [
|
|
79
|
+
{
|
|
80
|
+
"name": "Yannick Adam",
|
|
81
|
+
"url": "https://github.com/yannickadam",
|
|
82
|
+
"email": "yannickadam@users.noreply.github.com"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "Kilian Panot",
|
|
86
|
+
"url": "https://github.com/kpanot",
|
|
87
|
+
"email": "kpanot@users.noreply.github.com"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"name": "Jeremy Bourgeois",
|
|
91
|
+
"url": "https://github.com/jbourgeois-1A",
|
|
92
|
+
"email": "jbourgeois-1A@users.noreply.github.com"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"name": "Pierre Henri Ginoux",
|
|
96
|
+
"url": "https://github.com/pginoux-1A",
|
|
97
|
+
"email": "pginoux-1A@users.noreply.github.com"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "Mircea Vasile Rednic",
|
|
101
|
+
"url": "https://github.com/mrednic-1A",
|
|
102
|
+
"email": "mrednic-1A@users.noreply.github.com"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "Stephane Dalle",
|
|
106
|
+
"url": "https://github.com/sdalle-1A",
|
|
107
|
+
"email": "sdalle-1A@users.noreply.github.com"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"name": "Nicolas Hoffmann",
|
|
111
|
+
"url": "https://github.com/nhoffmann-1A",
|
|
112
|
+
"email": "nhoffmann-1A@users.noreply.github.com"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"name": "Victor Scaiceanu",
|
|
116
|
+
"url": "https://github.com/vscaiceanu-1a",
|
|
117
|
+
"email": "vscaiceanu-1A@users.noreply.github.com"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"name": "Florian Paul",
|
|
121
|
+
"url": "https://github.com/fpaul-1A",
|
|
122
|
+
"email": "fpaul-1A@users.noreply.github.com"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"name": "Corinne Paulve",
|
|
126
|
+
"url": "https://github.com/cpaulve-1A",
|
|
127
|
+
"email": "cpaulve-1A@users.noreply.github.com"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "Matthieu Crouzet",
|
|
131
|
+
"url": "https://github.com/matthieu-crouzet",
|
|
132
|
+
"email": "matthieu-crouzet@users.noreply.github.com"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"name": "Salome Do",
|
|
136
|
+
"url": "https://github.com/sdo-1A",
|
|
137
|
+
"email": "sdo-1A@users.noreply.github.com"
|
|
138
|
+
}
|
|
139
|
+
],
|
|
140
|
+
"bugs": "https://github.com/AmadeusITGroup/otter/issues",
|
|
141
|
+
"repository": {
|
|
142
|
+
"type": "git",
|
|
143
|
+
"url": "git+https://github.com/AmadeusITGroup/otter.git"
|
|
144
|
+
},
|
|
145
|
+
"license": "BSD-3-Clause",
|
|
146
|
+
"homepage": "https://amadeusitgroup.github.io/otter/"
|
|
147
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
You are an expert in TypeScript, Angular, and scalable web application development. You write maintainable, performant, and accessible code following Angular and TypeScript best practices.
|
|
2
|
+
|
|
3
|
+
## TypeScript Best Practices
|
|
4
|
+
|
|
5
|
+
- Use strict type checking
|
|
6
|
+
- Prefer type inference when the type is obvious
|
|
7
|
+
- Avoid the `any` type; use `unknown` when type is uncertain
|
|
8
|
+
|
|
9
|
+
## Angular Best Practices
|
|
10
|
+
|
|
11
|
+
- Always use standalone components over NgModules
|
|
12
|
+
- Must NOT set `standalone: true` inside Angular decorators. It's the default.
|
|
13
|
+
- Use signals for state management
|
|
14
|
+
- Implement lazy loading for feature routes
|
|
15
|
+
- Do NOT use the `@HostBinding` and `@HostListener` decorators. Put host bindings inside the `host` object of the `@Component` or `@Directive` decorator instead
|
|
16
|
+
- Use `NgOptimizedImage` for all static images.
|
|
17
|
+
- `NgOptimizedImage` does not work for inline base64 images.
|
|
18
|
+
|
|
19
|
+
## Components
|
|
20
|
+
|
|
21
|
+
- Keep components small and focused on a single responsibility
|
|
22
|
+
- Use `input()` and `output()` functions instead of decorators
|
|
23
|
+
- Use `computed()` for derived state
|
|
24
|
+
- Set `changeDetection: ChangeDetectionStrategy.OnPush` in `@Component` decorator
|
|
25
|
+
- Prefer inline templates for small components
|
|
26
|
+
- Prefer Reactive forms instead of Template-driven ones
|
|
27
|
+
- Do NOT use `ngClass`, use `class` bindings instead
|
|
28
|
+
- DO NOT use `ngStyle`, use `style` bindings instead
|
|
29
|
+
|
|
30
|
+
## State Management
|
|
31
|
+
|
|
32
|
+
- Use signals for local component state
|
|
33
|
+
- Use `computed()` for derived state
|
|
34
|
+
- Keep state transformations pure and predictable
|
|
35
|
+
- Do NOT use `mutate` on signals, use `update` or `set` instead
|
|
36
|
+
|
|
37
|
+
## Templates
|
|
38
|
+
|
|
39
|
+
- Keep templates simple and avoid complex logic
|
|
40
|
+
- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch`
|
|
41
|
+
- Use the async pipe to handle observables
|
|
42
|
+
|
|
43
|
+
## Services
|
|
44
|
+
|
|
45
|
+
- Design services around a single responsibility
|
|
46
|
+
- Use the `providedIn: 'root'` option for singleton services
|
|
47
|
+
- Use the `inject()` function instead of constructor injection
|
|
48
|
+
|
|
49
|
+
## Common pitfalls
|
|
50
|
+
|
|
51
|
+
- Control flow (`@if`):
|
|
52
|
+
- You cannot use `as` expressions in `@else if (...)`. E.g. invalid code: `@else if (bla(); as x)`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"best-practices.d.ts","sourceRoot":"","sources":["../../src/tools/best-practices.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,SAAS,EACV,MAAM,yCAAyC,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmCjE"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerBestPracticesTool = registerBestPracticesTool;
|
|
4
|
+
const promises_1 = require("node:fs/promises");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
/**
|
|
7
|
+
* Register the best practices tool.
|
|
8
|
+
* @param server
|
|
9
|
+
*/
|
|
10
|
+
function registerBestPracticesTool(server) {
|
|
11
|
+
server.registerTool('get_best_practices', {
|
|
12
|
+
title: 'Get Otter Coding Best Practices Guide',
|
|
13
|
+
description: 'You **MUST** use this tool to retrieve the Otter Best Practices Guide '
|
|
14
|
+
+ 'before any interaction with Otter and Angular code (creating, analyzing, modifying). '
|
|
15
|
+
+ 'It is mandatory to follow this guide to ensure all code adheres to '
|
|
16
|
+
+ 'modern standards. This is the first step for any Otter task.',
|
|
17
|
+
annotations: {
|
|
18
|
+
readOnlyHint: true,
|
|
19
|
+
openWorldHint: false
|
|
20
|
+
}
|
|
21
|
+
}, async () => {
|
|
22
|
+
// Logging as error as recommended by modelcontextprotocol.io (https://modelcontextprotocol.io/quickstart/server#quick-examples-2)
|
|
23
|
+
console.error('Fetching best practices guide...');
|
|
24
|
+
const text = await (0, promises_1.readFile)((0, node_path_1.join)(__dirname, '..', 'resources', 'instructions', 'best-practices.md'), 'utf8');
|
|
25
|
+
// Logging as error as recommended by modelcontextprotocol.io (https://modelcontextprotocol.io/quickstart/server#quick-examples-2)
|
|
26
|
+
console.error('Best practices guide fetched successfully.');
|
|
27
|
+
return {
|
|
28
|
+
content: [
|
|
29
|
+
{
|
|
30
|
+
type: 'text',
|
|
31
|
+
text
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=best-practices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"best-practices.js","sourceRoot":"","sources":["../../src/tools/best-practices.ts"],"names":[],"mappings":";;AAcA,8DAmCC;AAjDD,+CAE0B;AAC1B,yCAEmB;AAKnB;;;GAGG;AACH,SAAgB,yBAAyB,CAAC,MAAiB;IACzD,MAAM,CAAC,YAAY,CACjB,oBAAoB,EACpB;QACE,KAAK,EAAE,uCAAuC;QAC9C,WAAW,EACT,wEAAwE;cACtE,uFAAuF;cACvF,qEAAqE;cACrE,8DAA8D;QAClE,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,IAAI,EAAE;QACT,kIAAkI;QAClI,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,MAAM,IAAA,mBAAQ,EACzB,IAAA,gBAAI,EAAC,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,cAAc,EAAE,mBAAmB,CAAC,EACvE,MAAM,CACP,CAAC;QACF,kIAAkI;QAClI,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAE5D,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI;iBACL;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
/**
|
|
3
|
+
* Register the create monorepo with app tool.
|
|
4
|
+
* @param server
|
|
5
|
+
*/
|
|
6
|
+
export declare function registerCreateMonorepoWithAppTool(server: McpServer): void;
|
|
7
|
+
//# sourceMappingURL=create-monorepo-with-app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-monorepo-with-app.d.ts","sourceRoot":"","sources":["../../src/tools/create-monorepo-with-app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACV,MAAM,yCAAyC,CAAC;AAKjD;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2BzE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerCreateMonorepoWithAppTool = registerCreateMonorepoWithAppTool;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
/**
|
|
6
|
+
* Register the create monorepo with app tool.
|
|
7
|
+
* @param server
|
|
8
|
+
*/
|
|
9
|
+
function registerCreateMonorepoWithAppTool(server) {
|
|
10
|
+
server.registerTool('create_monorepo_with_app', {
|
|
11
|
+
title: 'Create Monorepo with App',
|
|
12
|
+
description: 'You **MUST** use this tool to create a monorepo with an application inside.'
|
|
13
|
+
+ 'It is mandatory to follow this guide to ensure all code adheres to '
|
|
14
|
+
+ 'Otter standards. This is the first step for any Otter repository.',
|
|
15
|
+
inputSchema: {
|
|
16
|
+
repositoryName: zod_1.z.string().describe('The name of the repository to create.'),
|
|
17
|
+
applicationName: zod_1.z.string().describe('The name of the application to create inside the monorepo.').optional()
|
|
18
|
+
}
|
|
19
|
+
}, ({ repositoryName, applicationName }) => {
|
|
20
|
+
return {
|
|
21
|
+
content: [
|
|
22
|
+
{
|
|
23
|
+
type: 'text',
|
|
24
|
+
text: 'To create a monorepo with an application, follow the steps outlined in the Otter documentation. \n'
|
|
25
|
+
+ `First run: npm create @o3r ${repositoryName}\n`
|
|
26
|
+
+ `Then run: cd ${repositoryName} && npm exec ng g application ${applicationName || 'frontend'}\n`
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=create-monorepo-with-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-monorepo-with-app.js","sourceRoot":"","sources":["../../src/tools/create-monorepo-with-app.ts"],"names":[],"mappings":";;AAWA,8EA2BC;AAnCD,6BAEa;AAEb;;;GAGG;AACH,SAAgB,iCAAiC,CAAC,MAAiB;IACjE,MAAM,CAAC,YAAY,CACjB,0BAA0B,EAC1B;QACE,KAAK,EAAE,0BAA0B;QACjC,WAAW,EACT,6EAA6E;cAC3E,qEAAqE;cACrE,mEAAmE;QACvE,WAAW,EAAE;YACX,cAAc,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;YAC5E,eAAe,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC,CAAC,QAAQ,EAAE;SAC9G;KACF,EACD,CAAC,EAAE,cAAc,EAAE,eAAe,EAAE,EAAE,EAAE;QACtC,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,oGAAoG;0BACtG,8BAA8B,cAAc,IAAI;0BAChD,gBAAgB,cAAc,iCAAiC,eAAe,IAAI,UAAU,IAAI;iBACrG;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|