diff --git a/README.md b/README.md index bde1b86..8035bec 100644 --- a/README.md +++ b/README.md @@ -378,6 +378,7 @@ With different `USE_API_URL_PREFIX` settings: - **Server Management**: Start, stop, rebuild, and check endpoints - **Endpoint Creation**: Generate new API endpoints via LLM +- **Media Creation**: Ask the LLM to Generate images and videos to serve locally  @@ -385,6 +386,8 @@ With different `USE_API_URL_PREFIX` settings:  + + ### Debugging MCP Test the MCP server with the inspector: diff --git a/cypress/e2e/demo-endpoints-spec.cy.ts b/cypress/e2e/demo-endpoints-spec.cy.ts index e5d0506..df51a77 100644 --- a/cypress/e2e/demo-endpoints-spec.cy.ts +++ b/cypress/e2e/demo-endpoints-spec.cy.ts @@ -1,186 +1,232 @@ const catsSchema = { - $schema: 'http://json-schema.org/draft-04/schema#', - type: 'array', - items: [ - { - type: 'object', - properties: { - id: { - type: 'integer', - }, - type: { - type: 'string', - }, - name: { - type: 'string', - }, - starSign: { - type: 'string', - }, - }, - required: ['id', 'type', 'name', 'starSign'], - }, - { - type: 'object', - properties: { - id: { - type: 'integer', - }, - type: { - type: 'string', - }, - name: { - type: 'string', - }, - starSign: { - type: 'string', - }, - }, - required: ['id', 'type', 'name', 'starSign'], - }, - { - type: 'object', - properties: { - id: { - type: 'integer', - }, - type: { - type: 'string', - }, - name: { - type: 'string', - }, - starSign: { - type: 'string', - }, - }, - required: ['id', 'type', 'name', 'starSign'], - }, - { - type: 'object', - properties: { - id: { - type: 'integer', - }, - type: { - type: 'string', - }, - name: { - type: 'string', - }, - starSign: { - type: 'string', - }, - }, - required: ['id', 'type', 'name', 'starSign'], - }, - ], + $schema: 'http://json-schema.org/draft-04/schema#', + type: 'array', + items: [ + { + type: 'object', + properties: { + id: { + type: 'integer', + }, + type: { + type: 'string', + }, + name: { + type: 'string', + }, + starSign: { + type: 'string', + }, + }, + required: ['id', 'type', 'name', 'starSign'], + }, + { + type: 'object', + properties: { + id: { + type: 'integer', + }, + type: { + type: 'string', + }, + name: { + type: 'string', + }, + starSign: { + type: 'string', + }, + }, + required: ['id', 'type', 'name', 'starSign'], + }, + { + type: 'object', + properties: { + id: { + type: 'integer', + }, + type: { + type: 'string', + }, + name: { + type: 'string', + }, + starSign: { + type: 'string', + }, + }, + required: ['id', 'type', 'name', 'starSign'], + }, + { + type: 'object', + properties: { + id: { + type: 'integer', + }, + type: { + type: 'string', + }, + name: { + type: 'string', + }, + starSign: { + type: 'string', + }, + }, + required: ['id', 'type', 'name', 'starSign'], + }, + ], }; describe('Cats demo endpoint contains expected information', () => { - it('checks server is running and serving data', () => { - cy.request('/api/cats').then((response) => { - expect(response.status).to.eq(200); - expect(response.body).length.to.be.greaterThan(0); - }); - }); + it('checks server is running and serving data', () => { + cy.request('/api/cats').then((response) => { + expect(response.status).to.eq(200); + expect(response.body).length.to.be.greaterThan(0); + }); + }); - it('should validate returned JSON against schema', () => { - cy.request('GET', '/api/cats').then((response) => { - expect(response.body).to.be.jsonSchema(catsSchema); - }); - }); + it('should validate returned JSON against schema', () => { + cy.request('GET', '/api/cats').then((response) => { + expect(response.body).to.be.jsonSchema(catsSchema); + }); + }); }); describe('Bikes demo endpoint contains expected information', () => { - it('checks server is running and serving data from GET requests with no url params', () => { - cy.request('GET', '/api/bikes').then((response) => { - expect(response.status).to.eq(200); + it('checks server is running and serving data from GET requests with no url params', () => { + cy.request('GET', '/api/bikes').then((response) => { + expect(response.status).to.eq(200); - expect(response.body).to.deep.equal({ - response: - 'this is a GET test response from api/bikes for bike type: none', - }); - }); - }); + expect(response.body).to.deep.equal({ + response: + 'this is a GET test response from api/bikes for bike type: none', + }); + }); + }); - it('checks server is running and serving data from GET requests with url params', () => { - cy.request('GET', '/api/bikes?type=KawasakiNinja').then((response) => { - expect(response.status).to.eq(200); + it('checks server is running and serving data from GET requests with url params', () => { + cy.request('GET', '/api/bikes?type=KawasakiNinja').then((response) => { + expect(response.status).to.eq(200); - expect(response.body).to.deep.equal({ - response: - 'this is a GET test response from api/bikes for bike type: KawasakiNinja', - }); - }); - }); + expect(response.body).to.deep.equal({ + response: + 'this is a GET test response from api/bikes for bike type: KawasakiNinja', + }); + }); + }); - it('checks server is running and serving data from POST requests', () => { - cy.request('POST', '/api/bikes', { - id: 6, - userId: 'Mario', - title: 'Favourite Bike', - body: '{favouriteBike: "Kawasaki Ninja"}', - }).then((response) => { - expect(response.status).to.eq(200); - cy.log(response.body); + it('checks server is running and serving data from POST requests', () => { + cy.request('POST', '/api/bikes', { + id: 6, + userId: 'Mario', + title: 'Favourite Bike', + body: '{favouriteBike: "Kawasaki Ninja"}', + }).then((response) => { + expect(response.status).to.eq(200); + cy.log(response.body); - expect(response.body).to.deep.equal({ - response: - 'this is a POST test response from api/bikes with bodyData {"id":6,"userId":"Mario","title":"Favourite Bike","body":"{favouriteBike: \\"Kawasaki Ninja\\"}"}', - }); - }); - }); + expect(response.body).to.deep.equal({ + response: + 'this is a POST test response from api/bikes with bodyData {"id":6,"userId":"Mario","title":"Favourite Bike","body":"{favouriteBike: \\"Kawasaki Ninja\\"}"}', + }); + }); + }); }); describe('Images demo endpoint contains expected information', () => { - it('checks image endpoint is running', () => { - cy.visit('/api/images'); - cy.get('h4').contains( - 'Access images stored in the src/resources/images folder using the format:', - ); - cy.get('h4').contains('Example: api/images/placeholder.png'); - }); - it('checks placeholder image demo endpoint is running', () => { - cy.request('/api/images/placeholder.png').then((response) => { - expect(response.status).to.eq(200); - }); - }); - it('checks placeholder image can be resized', () => { - cy.request('/api/images/placeholder.png?height=200&width=300').then( - (response) => { - expect(response.status).to.eq(200); - }, - ); - }); + it('checks image endpoint is running', () => { + cy.visit('/api/images'); + cy.get('h4').contains( + 'Access images stored in the src/resources/images folder using the format:', + ); + cy.get('h4').contains( + 'Available image files in src/resources/images folder:', + ); + }); + it('checks placeholder image demo endpoint is running', () => { + cy.request('/api/images/placeholder.png').then((response) => { + expect(response.status).to.eq(200); + }); + }); + it('checks placeholder image can be resized', () => { + cy.request('/api/images/placeholder.png?height=200&width=300').then( + (response) => { + expect(response.status).to.eq(200); + }, + ); + }); + it(`checks images list can be accessed`, () => { + const jsonSchemaImages = { + type: 'object', + properties: { + mediaType: { + type: 'string', + }, + files: { + type: 'array', + items: { + type: 'string', + }, + }, + }, + required: ['mediaType', 'files'], + }; + cy.request('/api/images/list').then((response) => { + expect(response.status).to.eq(200); + expect(response.body).to.be.jsonSchema(jsonSchemaImages); + }); + }); }); describe('Videos demo endpoint contains expected information', () => { - it('checks image endpoint is running', () => { - cy.visit('/api/videos'); - cy.get('h4').contains( - 'Access videos stored in the src/resources/videos folder using the format:', - ); - cy.get('h4').contains('Example: api/videos/placeholder.mp4'); - }); - it('checks placeholder image demo endpoint is running', () => { - cy.request('/api/videos/placeholder.mp4').then((response) => { - expect(response.status).to.eq(200); - }); - }); + it('checks image endpoint is running', () => { + cy.visit('/api/videos'); + cy.get('h4').contains( + 'Access videos stored in the src/resources/videos folder using the format:', + ); + cy.get('h4').contains( + 'Available video files in src/resources/videos folder:', + ); + }); + it('checks placeholder image demo endpoint is running', () => { + cy.request('/api/videos/placeholder.mp4').then((response) => { + expect(response.status).to.eq(200); + }); + }); + it(`checks videos list can be accessed`, () => { + const jsonSchemaVideos = { + type: 'object', + properties: { + mediaType: { + type: 'string', + }, + files: { + type: 'array', + items: { + type: 'string', + }, + }, + }, + required: ['mediaType', 'files'], + }; + cy.request('/api/videos/list').then((response) => { + expect(response.status).to.eq(200); + expect(response.body).to.be.jsonSchema(jsonSchemaVideos); + }); + }); }); describe('Markdown demo endpoint contains expected information', () => { - it('checks markdown endpoint is running', () => { - cy.visit('/api/markdown'); - cy.get('h4').contains( - 'Access markdown files stored in the src/resources/markdown folder using the format:', - ); - cy.get('h4').contains('Example: api/markdown/demo'); - }); - it('checks placeholder image demo endpoint is running', () => { - cy.visit('/api/markdown/demo'); - cy.get('h1').contains('This is a test markdown file'); - cy.get('h2').contains('Add files into the src/markdown directory'); - }); + it('checks markdown endpoint is running', () => { + cy.visit('/api/markdown'); + cy.get('h4').contains( + 'Access markdown files stored in the src/resources/markdown folder using the format:', + ); + cy.get('h4').contains('Example: api/markdown/demo'); + }); + it('checks placeholder image demo endpoint is running', () => { + cy.visit('/api/markdown/demo'); + cy.get('h1').contains('This is a test markdown file'); + cy.get('h2').contains('Add files into the src/markdown directory'); + }); }); diff --git a/images/mcp-4.png b/images/mcp-4.png new file mode 100644 index 0000000..8dd4b69 Binary files /dev/null and b/images/mcp-4.png differ diff --git a/package-lock.json b/package-lock.json index 4d9d878..6e0307b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "": { "dependencies": { "@faker-js/faker": "^9.8.0", - "@modelcontextprotocol/sdk": "^1.12.3", + "@modelcontextprotocol/sdk": "^1.13.1", "@mswjs/data": "^0.16.2", "@mswjs/http-middleware": "^0.10.3", "@types/chai-json-schema": "^1.4.10", @@ -29,12 +29,12 @@ "@commitlint/cli": "^19.8.1", "@commitlint/config-conventional": "^19.8.1", "@types/aws-lambda": "^8.10.150", - "@types/node": "^24.0.3", - "cypress": "^14.4.1", + "@types/node": "^24.0.4", + "cypress": "^14.5.0", "husky": "^9.1.7", "lint-staged": "^16.1.2", - "oxlint": "^1.1.0", - "prettier": "3.5.3", + "oxlint": "^1.3.0", + "prettier": "3.6.1", "start-server-and-test": "^2.0.12" } }, @@ -1579,9 +1579,9 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.12.3.tgz", - "integrity": "sha512-DyVYSOafBvk3/j1Oka4z5BWT8o4AFmoNyZY9pALOm7Lh3GZglR71Co4r4dEUoqDWdDazIZQHBe7J2Nwkg6gHgQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.13.1.tgz", + "integrity": "sha512-8q6+9aF0yA39/qWT/uaIj6zTpC+Qu07DnN/lb9mjoquCJsAh6l3HyYqc9O3t2j7GilseOQOQimLg7W3By6jqvg==", "license": "MIT", "dependencies": { "ajv": "^6.12.6", @@ -2025,9 +2025,9 @@ "license": "MIT" }, "node_modules/@oxlint/darwin-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oxlint/darwin-arm64/-/darwin-arm64-1.1.0.tgz", - "integrity": "sha512-sSnR3SOxIU/QfaqXrcQ0UVUkzJO0bcInQ7dMhHa102gVAgWjp1fBeMVCM0adEY0UNmEXrRkgD/rQtQgn9YAU+w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-arm64/-/darwin-arm64-1.3.0.tgz", + "integrity": "sha512-TcCaETXYfiEfS+u/gZNND4WwEEtnJJjqg8BIC56WiCQDduYTvmmbQ0vxtqdNXlFzlvmRpZCSs7qaqXNy8/8FLA==", "cpu": [ "arm64" ], @@ -2039,9 +2039,9 @@ ] }, "node_modules/@oxlint/darwin-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oxlint/darwin-x64/-/darwin-x64-1.1.0.tgz", - "integrity": "sha512-Jvd3fHnzY2OYbmsg9NSGPoBkGViDGHSFnBKyJQ9LOIw7lxAyQBG2Quxc3GYPFR/f9OYho9C3p4+dIaAJfKhnsw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-x64/-/darwin-x64-1.3.0.tgz", + "integrity": "sha512-REgq9s1ZWuh++Vi+mUPNddLTp/D+iu+T8nLd3QM1dzQoBD/SZ7wRX3Mdv8QGT/m8dknmDBQuKAP6T47ox9HRSA==", "cpu": [ "x64" ], @@ -2053,9 +2053,9 @@ ] }, "node_modules/@oxlint/linux-arm64-gnu": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-gnu/-/linux-arm64-gnu-1.1.0.tgz", - "integrity": "sha512-MgW4iskOdXuoR+wDXIJUfbdnTg2eo2FnQRaD6ZqhnDTDa7LnV+06rp/Cg3aGj2X9jSEcKDv/bMbYQuot7WRs6Q==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-gnu/-/linux-arm64-gnu-1.3.0.tgz", + "integrity": "sha512-QAS8AWKDcDeUe8mJaw/pF2D9+js8FbFTo75AiekZKNm9V6QAAiCkyvesmILD8RrStw9aV2D/apOD71vsfcDoGA==", "cpu": [ "arm64" ], @@ -2067,9 +2067,9 @@ ] }, "node_modules/@oxlint/linux-arm64-musl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-musl/-/linux-arm64-musl-1.1.0.tgz", - "integrity": "sha512-a+pkEKmDRdrW+y0gtZ/m68ElVW2VZgATGbMxDgDYFpdiMx9Y0pUPwTMZ2EX/17Aslop4c1BiDSFDK7aEBxKR2g==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-musl/-/linux-arm64-musl-1.3.0.tgz", + "integrity": "sha512-rAbz0KFkk5GPdERoFO4ZUZmVkECnHXjRG0O2MeT5zY7ddlyZUjEk1cWjw+HCtWVdKkqhZJeNFMuEiRLkpzBIIw==", "cpu": [ "arm64" ], @@ -2081,9 +2081,9 @@ ] }, "node_modules/@oxlint/linux-x64-gnu": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-gnu/-/linux-x64-gnu-1.1.0.tgz", - "integrity": "sha512-wNBsXCKVZMvUTcFitrV1wTsdhUAv8l+XQxHxciZ2SO6dpNnWEb2YCxSAIOXeyzBLdO4pIODYcSy38CvGue7TwA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-gnu/-/linux-x64-gnu-1.3.0.tgz", + "integrity": "sha512-6uLO1WsJwCtVNGHtjXwg2TRvxQYttYJKMjSdv6RUXGWY1AI+/+yHzvu+phU/F40uNC7CFhFnqWDuPaSZ49hdAQ==", "cpu": [ "x64" ], @@ -2095,9 +2095,9 @@ ] }, "node_modules/@oxlint/linux-x64-musl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-musl/-/linux-x64-musl-1.1.0.tgz", - "integrity": "sha512-pZD0lt6A5j2Wp70fgIYk4GoPfKTZ8mHWamWIpKFT7aSkFkiOi6nhLWDFvMEIHWRTK3LgkWUNcnWPp4brvin4wQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-musl/-/linux-x64-musl-1.3.0.tgz", + "integrity": "sha512-+vrmJUHgtJmgIo+L9eTP04NI/OQNCOZtQo6I49qGWc9cpr+0MnIh9KMcyAOxmzVTF5g+CF1I/1bUz4pk4I3LDw==", "cpu": [ "x64" ], @@ -2109,9 +2109,9 @@ ] }, "node_modules/@oxlint/win32-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oxlint/win32-arm64/-/win32-arm64-1.1.0.tgz", - "integrity": "sha512-rT6uXQvE80+B+L04HJf30uF26426FPI9i9DAY2AxBUhrpNwhqkDEhQdd9ilFWVC7SSbpHgAs50lo+ImSAAkHPQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@oxlint/win32-arm64/-/win32-arm64-1.3.0.tgz", + "integrity": "sha512-k+ETUVl+O3b8Rcd2PP5V3LqQ2QoN/TOX2f19XXHZEynbVLY3twLYPb3hLdXqoo7CKRq3RJdTfn1upHH48/qrZQ==", "cpu": [ "arm64" ], @@ -2123,9 +2123,9 @@ ] }, "node_modules/@oxlint/win32-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oxlint/win32-x64/-/win32-x64-1.1.0.tgz", - "integrity": "sha512-x6r5yvM3wEty93Bx0NuNK+kutUyS/K55itkUrxdExoK6GcmVDboGGuhju9HyU2cM/IWLEWO8RHcXSyaxr9GR5g==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@oxlint/win32-x64/-/win32-x64-1.3.0.tgz", + "integrity": "sha512-nWSgK0fT02TQ/BiAUCd13BaobtHySkCDcQaL+NOmhgeb0tNWjtYiktuluahaIqFcYJPWczVlbs8DU/Eqo8vsug==", "cpu": [ "x64" ], @@ -2297,9 +2297,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.0.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.3.tgz", - "integrity": "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg==", + "version": "24.0.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.4.tgz", + "integrity": "sha512-ulyqAkrhnuNq9pB76DRBTkcS6YsmDALy6Ua63V8OhrOBgbcYt6IOdzpw5P1+dyRIyMerzLkeYWBeOXPpA9GMAA==", "license": "MIT", "dependencies": { "undici-types": "~7.8.0" @@ -3349,9 +3349,9 @@ } }, "node_modules/cypress": { - "version": "14.4.1", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-14.4.1.tgz", - "integrity": "sha512-YSGvVXtTqSGRTyHbaxHI5dHU/9xc5ymaTIM4BU85GKhj980y6XgA3fShSpj5DatS8knXMsAvYItQxVQFHGpUtw==", + "version": "14.5.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-14.5.0.tgz", + "integrity": "sha512-1HOnKvWep0LkWuFwPeWkZ0TDl7ivi2/Mz+WNU4dfkeLJaFndS3Ow6TXT7YjuTqLFI2peJKzPKljVUFdymI2K5g==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -3382,6 +3382,7 @@ "figures": "^3.2.0", "fs-extra": "^9.1.0", "getos": "^3.2.1", + "hasha": "5.2.2", "is-installed-globally": "~0.4.0", "lazy-ass": "^1.6.0", "listr2": "^3.8.3", @@ -4778,6 +4779,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -6001,9 +6029,9 @@ "license": "MIT" }, "node_modules/oxlint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.1.0.tgz", - "integrity": "sha512-OVNpaoaQCUHHhCv5sYMPJ7Ts5k7ziw0QteH1gBSwF3elf/8GAew2Uh/0S7HsU1iGtjhlFy80+A8nwIb3Tq6m1w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.3.0.tgz", + "integrity": "sha512-PzAOmPxnXYpVF1q6h9pkOPH6uJ/44XrtFWJ8JcEMpoEq9HISNelD3lXhACtOAW8CArjLy/qSlu2KkyPxnXgctA==", "dev": true, "license": "MIT", "bin": { @@ -6017,14 +6045,14 @@ "url": "https://github.com/sponsors/Boshen" }, "optionalDependencies": { - "@oxlint/darwin-arm64": "1.1.0", - "@oxlint/darwin-x64": "1.1.0", - "@oxlint/linux-arm64-gnu": "1.1.0", - "@oxlint/linux-arm64-musl": "1.1.0", - "@oxlint/linux-x64-gnu": "1.1.0", - "@oxlint/linux-x64-musl": "1.1.0", - "@oxlint/win32-arm64": "1.1.0", - "@oxlint/win32-x64": "1.1.0" + "@oxlint/darwin-arm64": "1.3.0", + "@oxlint/darwin-x64": "1.3.0", + "@oxlint/linux-arm64-gnu": "1.3.0", + "@oxlint/linux-arm64-musl": "1.3.0", + "@oxlint/linux-x64-gnu": "1.3.0", + "@oxlint/linux-x64-musl": "1.3.0", + "@oxlint/win32-arm64": "1.3.0", + "@oxlint/win32-x64": "1.3.0" } }, "node_modules/p-map": { @@ -6190,9 +6218,9 @@ } }, "node_modules/prettier": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", - "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.1.tgz", + "integrity": "sha512-5xGWRa90Sp2+x1dQtNpIpeOQpTDBs9cZDmA/qs2vDNN2i18PdapqY7CmBeyLlMuGqXJRIOPaCaVZTLNQRWUH/A==", "dev": true, "license": "MIT", "bin": { diff --git a/package.json b/package.json index 806ae4d..a155e86 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "dependencies": { "@faker-js/faker": "^9.8.0", - "@modelcontextprotocol/sdk": "^1.12.3", + "@modelcontextprotocol/sdk": "^1.13.1", "@mswjs/data": "^0.16.2", "@mswjs/http-middleware": "^0.10.3", "@types/chai-json-schema": "^1.4.10", @@ -44,12 +44,12 @@ "@commitlint/cli": "^19.8.1", "@commitlint/config-conventional": "^19.8.1", "@types/aws-lambda": "^8.10.150", - "@types/node": "^24.0.3", - "cypress": "^14.4.1", + "@types/node": "^24.0.4", + "cypress": "^14.5.0", "husky": "^9.1.7", "lint-staged": "^16.1.2", - "oxlint": "^1.1.0", - "prettier": "3.5.3", + "oxlint": "^1.3.0", + "prettier": "3.6.1", "start-server-and-test": "^2.0.12" }, "lint-staged": { diff --git a/src/api/images/api.ts b/src/api/images/api.ts index 37313a1..4a2095c 100644 --- a/src/api/images/api.ts +++ b/src/api/images/api.ts @@ -8,11 +8,16 @@ import sharp from 'sharp'; function handler(pathName: string) { return [ http.get(`/${pathName}`, () => { + const images = fs.readdirSync('./src/resources/images'); return HttpResponse.text( `