From 4c7354c3ec2598bcccc684317c6b161c22eef50b Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Fri, 10 Jul 2026 00:24:12 +0000 Subject: [PATCH] ## Mcp-typescript SDK Changes: * `CloudinarySMD.metadata_fields.createMetadataField()`: * `request` **Changed** * `response` **Changed** * `CloudinarySMD.metadata_fields.listMetadataFields()`: `response.metadata_fields[]` **Changed** * `CloudinarySMD.metadata_fields.getMetadataField()`: `response` **Changed** * `CloudinarySMD.metadata_fields.updateMetadataField()`: * `request.metadata_field` **Changed** * `response` **Changed** --- .speakeasy/gen.lock | 124 +++++++++++++--------------- .speakeasy/gen.yaml | 2 +- .speakeasy/workflow.lock | 12 +-- README.md | 4 +- RELEASES.md | 10 ++- manifest.json | 2 +- package-lock.json | 16 ++-- package.json | 6 +- src/landing-page.ts | 2 +- src/lib/config.ts | 8 +- src/lib/dlv.ts | 53 ------------ src/lib/encodings.ts | 2 +- src/lib/env.ts | 9 +- src/lib/http.ts | 4 +- src/lib/is-plain-object.ts | 43 ---------- src/lib/primitives.ts | 16 ++++ src/lib/retries.ts | 8 ++ src/lib/security.ts | 15 ++-- src/mcp-server/mcp-server.ts | 2 +- src/mcp-server/server.ts | 2 +- src/mcp-server/tools.ts | 2 + src/models/createmetadatafieldop.ts | 26 ++++-- src/models/metadatafield.ts | 32 +++++-- src/types/async.ts | 15 ++-- src/types/bigint.ts | 35 ++++---- 25 files changed, 215 insertions(+), 235 deletions(-) delete mode 100644 src/lib/dlv.ts delete mode 100644 src/lib/is-plain-object.ts diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 5ab0496..4e92a37 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,24 +1,24 @@ lockVersion: 2.0.0 id: cce51212-9f48-488d-9ded-b8a6fac39957 management: - docChecksum: cf1dd98292170ae86b9dd82603a00442 - docVersion: 0.5.0 - speakeasyVersion: 1.761.10 - generationVersion: 2.881.16 - releaseVersion: 0.5.0 - configChecksum: 6a4b83610c89a26954d3eebd6a40b1a7 + docChecksum: 188eb722bb93f4242ac79e556474fefe + docVersion: 0.5.5 + speakeasyVersion: 1.789.1 + generationVersion: 2.916.4 + releaseVersion: 0.6.0 + configChecksum: 74228fdf9968aa2c8b559a4b9acc83c6 repoURL: https://github.com/cloudinary/structured-metadata-mcp.git installationURL: https://github.com/cloudinary/structured-metadata-mcp published: true persistentEdits: - generation_id: 858a4ad8-b668-4a29-9401-094d4d7af020 - pristine_commit_hash: c93f6d139ecdb52d1de1d3d0a453f55d82a3044c - pristine_tree_hash: 82e6bc27979dce6bcbd5bf0e144b6020d1de7ee6 + generation_id: d97d16d2-0a19-477e-b97e-a9221847e6e3 + pristine_commit_hash: 80d87cfc166a7c523d98cfc51ac4d831cea4dd53 + pristine_tree_hash: bc1d34fa1a4f7a52be24b449412753cb8cccca51 features: mcp-typescript: additionalDependencies: 0.1.0 constsAndDefaults: 0.1.2 - core: 1.2.27 + core: 1.3.6 customSecuritySchemes: 0.1.1 defaultEnabledRetries: 0.1.0 enumUnions: 0.1.0 @@ -30,7 +30,7 @@ features: hiddenGlobals: 0.1.0 nullables: 0.1.0 responseFormat: 0.1.1 - retries: 0.1.0 + retries: 0.1.1 sdkHooks: 0.3.0 unions: 0.2.0 trackedFiles: @@ -52,12 +52,12 @@ trackedFiles: pristine_git_object: 4f9e60a9462fc4def738d60c3aaadf8232ef185f manifest.json: id: ca642a226869 - last_write_checksum: sha1:91f6a72db84046bc1d5af60381f169d1bf5b449a - pristine_git_object: ff8cb4008e30eda000903e55866679ae11925358 + last_write_checksum: sha1:6af0b5ba67279eb6ab2c839f3b43baba39396404 + pristine_git_object: e977d13eeaafe47d4179cb97a8a24244fc0342f0 package.json: id: 7030d0b2f71b - last_write_checksum: sha1:b84df8d6f925fbf0fddc1567b67af0c0b295b854 - pristine_git_object: 84448549c30ea25880a1ed27a303b803b82f5c84 + last_write_checksum: sha1:7349cd0a3d81d646a052f8a3c774323d9aedd41c + pristine_git_object: 9e68f27929d104a34ac6cebbddbda55dabedd804 src/core.ts: id: f431fdbcd144 last_write_checksum: sha1:c3eb278d60e337fa723f4dea4358394b5e39e0fa @@ -140,56 +140,48 @@ trackedFiles: pristine_git_object: 9c36bf01332084f735909a71036c3544cc4c7e3a src/landing-page.ts: id: ef64a6ee46d7 - last_write_checksum: sha1:368bf559e70601b5ec5c5b65abe2366fb47176e6 - pristine_git_object: d6c164dda3dd1fe95b12001d004a9b7bc8b4c29d + last_write_checksum: sha1:c2cc9f965c8b9044c1dab990807545607eb71da7 + pristine_git_object: 803a26046ee1f16c27abaff36edc6faffa92389b src/lib/base64.ts: id: "598522066688" last_write_checksum: sha1:e9f04a037018040361043104960982f7c22db52d pristine_git_object: d4bd8b341290e7a828a171d840bd0b0fff7c7cd7 src/lib/config.ts: id: 320761608fb3 - last_write_checksum: sha1:4efe9f8eb4afc26ef4c02781b3883ff6bb600755 - pristine_git_object: 81816e8b0a80add3f50e6c23adb2c928ad77dc7c - src/lib/dlv.ts: - id: b1988214835a - last_write_checksum: sha1:1dd3e3fbb4550c4bf31f5ef997faff355d6f3250 - pristine_git_object: e81091f5e536f82739f71379b1fddc2d147c49e2 + last_write_checksum: sha1:1af5fa236bb56985ef3379b09924459a131d5399 + pristine_git_object: fecbf086c986ff7a354c6cd3e8c8cc4bde3070f5 src/lib/encodings.ts: id: 3bd8ead98afd - last_write_checksum: sha1:2bac07b55d30cf8618729e656b8becffc315fbdb - pristine_git_object: caa16bb379e5680ab114b44f6e3e5f0a2c836be3 + last_write_checksum: sha1:9b859366c917d31f7ee533176f71631872fb05fa + pristine_git_object: b19d1d002d9ec04f027250253ea9780ae7fd98c3 src/lib/env.ts: id: c52972a3b198 - last_write_checksum: sha1:69b6f701c443133139651cf64fbd54fe2bc5357f - pristine_git_object: 40c8651cc97a272072ea6c5a1b4d2ab086f07e70 + last_write_checksum: sha1:ffcbb6530c081321ccd7818c4fd432b176a5150e + pristine_git_object: 6f2ee7ca0ccdf2518367715c9a0550c8c8a69a44 src/lib/files.ts: id: e5efa54fcb95 last_write_checksum: sha1:795c14026405d547bfc47012f7ad9666e530fa7f pristine_git_object: 6ca6b37d35a12448da176ee2517cc036db12c81c src/lib/http.ts: id: 63a80782d37e - last_write_checksum: sha1:797cbf16d3c7c4d62d3ba0eedb08617524938457 - pristine_git_object: 13cf1fd7894a89f727b8d2db2ad24313a94f68c7 - src/lib/is-plain-object.ts: - id: b9862591096a - last_write_checksum: sha1:df687f25a9590b6fd95d39df41a652ae3fd4e517 - pristine_git_object: 61070d3d7c7e5e95b1ed7e7ea21869eb0767db77 + last_write_checksum: sha1:a56435907625a816051aa2131d60909c59f1da27 + pristine_git_object: 6b7a6cf3e281cae246708b1aca4a27730e08fe61 src/lib/logger.ts: id: 7ee7741a02bf last_write_checksum: sha1:0ec9d3a2a34c362746b767e4f9a746c055d57a7b pristine_git_object: d181f2937d4128afbe9b0327e0f81d1fa9c877b7 src/lib/primitives.ts: id: 74859f750b28 - last_write_checksum: sha1:d5fbb4e2feef5747fc8071046bdd4122c87bd066 - pristine_git_object: 668ab9d500d77bee730a619c5fda4a1d3cd1d16c + last_write_checksum: sha1:6f2cc1b00581006b4f70a853467df8cae81bc483 + pristine_git_object: 13567e79658831eeb0c696cf5982a170aa7e213a src/lib/result.ts: id: ab7a4c1c4c71 last_write_checksum: sha1:d24994d58f37a1ca106847fcc6d2e976c6f1c093 pristine_git_object: ccbe51eac69dfb0da5131f14fd753c4b47c1d527 src/lib/retries.ts: id: b24a69d15639 - last_write_checksum: sha1:f3da74dffcbe2756c69393f8600205aa1dc06e68 - pristine_git_object: e3ce9aba72150fc3c18f3105d39b21aba809377b + last_write_checksum: sha1:42c8f6cc4c875be236230a8c760f4f32d8c1ab68 + pristine_git_object: 21a647e1e9ae64817fcd63b5dd6bb5a51b63d225 src/lib/schemas.ts: id: deb4b531fae1 last_write_checksum: sha1:7c7ba40781682f6d44bb585b5016e2527b52660e @@ -200,8 +192,8 @@ trackedFiles: pristine_git_object: f30f835fcc61405e2474ab67e394c817efe55eec src/lib/security.ts: id: 0502afa7922e - last_write_checksum: sha1:53214b9aa59f4dab444b6941835938673e540758 - pristine_git_object: ba1aef127545a0bb98f592f7b92c31e88458d9a0 + last_write_checksum: sha1:5c36ea964c03de65013da08997f8d9069b9fb24b + pristine_git_object: 4baf554777195a56a253321b1ebbad7b5d22d9eb src/lib/url.ts: id: b0057e24ed76 last_write_checksum: sha1:9550819577dc1e514e61496167aefcc137238aaf @@ -244,8 +236,8 @@ trackedFiles: pristine_git_object: 441c1ce08678d15726f06f8692d00bd4f8daa5c0 src/mcp-server/mcp-server.ts: id: aabbc4ab07c1 - last_write_checksum: sha1:e39022de05b5a9abe737a429cdc9c1b4b5352c1e - pristine_git_object: d4af9d46cc8782e68b775591fe1d7aa7a6df84b6 + last_write_checksum: sha1:18d6f1dfaa22d75d8594d97642a77b10d51cabc6 + pristine_git_object: 68d8c1cbf342d3654ef085a279f96f4222850101 src/mcp-server/prompts.ts: id: 26f3d73cbf31 last_write_checksum: sha1:5ebf7a729762b1cd90afccecc101663b9905d181 @@ -260,16 +252,16 @@ trackedFiles: pristine_git_object: bc628748008f07f8d0fd75220d5015c46817b946 src/mcp-server/server.ts: id: 2784dd48e82a - last_write_checksum: sha1:1e6cc742152400161883d2961472ba835fef98c6 - pristine_git_object: 7be0d25a927526f804a88d0d2fbdb3a1b26fef7a + last_write_checksum: sha1:576a9ea4697461dab3f7c05b5e19d17e3fa75299 + pristine_git_object: 2c18887f6628ad019113ae705b9b10ec44236336 src/mcp-server/shared.ts: id: 074e80d4be1e last_write_checksum: sha1:19c9034032819a14f15c430de4350c8aba99d725 pristine_git_object: bb74a74788ebd7d11262f5f63b8fdd29ab817f48 src/mcp-server/tools.ts: id: 654d5d1f2062 - last_write_checksum: sha1:6028db1b23819165034617aad12f975a49a79e8a - pristine_git_object: df749737c868dfed77f14277b9d8dcadd0d4a7ff + last_write_checksum: sha1:ea1da7063967e24380790b1f3d44b2fdf75846e7 + pristine_git_object: c5158f179e00124e84e0abdf9f8b1fad8bc674f3 src/mcp-server/tools/metadataFieldsCreateMetadataField.ts: id: faf8adfc68d8 last_write_checksum: sha1:863fa224183143a0d18f8245b17aefabea18cf6d @@ -328,8 +320,8 @@ trackedFiles: pristine_git_object: cc0f4506eda169011bb7419ce94f30c88cbd2b90 src/models/createmetadatafieldop.ts: id: 22e1b361a5ea - last_write_checksum: sha1:9832344c0f1a84b7c7d5358ec42968170ab59a4f - pristine_git_object: ade6697e33635a8f149fc991c511b8b12c779945 + last_write_checksum: sha1:a0e134c96f8c9ba56104372984ff8a0a1a34f596 + pristine_git_object: f2564387535e1d2a6b857771f27d337609fd76c3 src/models/createmetadataruleop.ts: id: a04504005165 last_write_checksum: sha1:6de29a09fe04e3bcaf86b4eb574d818662c6c712 @@ -404,8 +396,8 @@ trackedFiles: pristine_git_object: ff1413093657cd37b449eb4c693f7a7ae30dc707 src/models/metadatafield.ts: id: 23e37dbac746 - last_write_checksum: sha1:4c56ce67ea772c9158332dc234eecd38628dd801 - pristine_git_object: ddda27ac3a9b84d483c136a713deba7d066d0bb7 + last_write_checksum: sha1:1113e639fb7e84699f53dd22e93d8ca1ff90fffa + pristine_git_object: e0b8a4e9541dda0e800e941d1c92976173697e3f src/models/metadatafielddatasourcevalue.ts: id: 51c7e4cb8022 last_write_checksum: sha1:f1d755b14d1a7fc4c22c971b94a928904976c743 @@ -512,12 +504,12 @@ trackedFiles: pristine_git_object: 83747003545feab99943372c90a4bce0c2806fb0 src/types/async.ts: id: fac8da972f86 - last_write_checksum: sha1:3ff07b3feaf390ec1aeb18ff938e139c6c4a9585 - pristine_git_object: 689dba5de50e8769e5f3bb913e3f42a146d15bc1 + last_write_checksum: sha1:675d04bb4b4081dc3482f18de98674f9b446e7b4 + pristine_git_object: 1543b95cf7be9b5a871d7395f259dbd65331dc21 src/types/bigint.ts: id: 3ca6e3280e43 - last_write_checksum: sha1:58178437a7d38f022b5d9bef691ba5539fad4655 - pristine_git_object: f32ee5fe6a2dbf82bd2d1ec7c17cd2987bcff1d6 + last_write_checksum: sha1:ebf6d4b27fc3aa7ff76dbedae9a19fb7f39e5dc7 + pristine_git_object: 91c22c4052617269c44ed145d678d39d8eb24a4d src/types/blobs.ts: id: f8ab9b326c86 last_write_checksum: sha1:9cc86e0e9420999afb48d53c57d71584be745fd7 @@ -549,10 +541,10 @@ examples: path: cloud_name: "" requestBody: - application/json: {"type": "set", "label": ""} + application/json: {"type": "set", "label": "", "alphabetically_sorted": true} responses: "200": - application/json: {} + application/json: {"alphabetically_sorted": true} "400": application/json: {"error": {"message": ""}} listMetadataFields: @@ -562,7 +554,7 @@ examples: cloud_name: "" responses: "200": - application/json: {} + application/json: {"metadata_fields": [{"alphabetically_sorted": true}]} "401": application/json: {"error": {"message": ""}} getMetadataField: @@ -573,7 +565,7 @@ examples: cloud_name: "" responses: "200": - application/json: {} + application/json: {"alphabetically_sorted": true} "401": application/json: {"error": {"message": ""}} updateMetadataField: @@ -583,10 +575,10 @@ examples: external_id: "" cloud_name: "" requestBody: - application/json: {} + application/json: {"alphabetically_sorted": true} responses: "200": - application/json: {} + application/json: {"alphabetically_sorted": true} "400": application/json: {"error": {"message": ""}} deleteMetadataField: @@ -621,7 +613,7 @@ examples: application/json: {"order_by": "external_id"} responses: "200": - application/json: {} + application/json: {"metadata_fields": [{"alphabetically_sorted": true}]} "400": application/json: {"error": {"message": ""}} reorderMetadataField: @@ -634,7 +626,7 @@ examples: application/json: {"position": 33651} responses: "200": - application/json: {} + application/json: {"metadata_fields": [{"alphabetically_sorted": true}]} "400": application/json: {"error": {"message": ""}} updateMetadataFieldDatasource: @@ -698,10 +690,10 @@ examples: path: cloud_name: "" requestBody: - application/json: {"metadata_field_id": "smd-field-1", "name": "My Rule", "condition": {"metadata_field_id": "smd-field-2", "populated": true}, "result": {"apply_value": {"value": "my value", "mode": "default"}}, "state": "active", "position": 1} + application/json: {"metadata_field_id": "smd-field-1", "name": "Disable field when other field is populated", "condition": {"metadata_field_id": "smd-field-2", "populated": true}, "result": {}, "state": "active", "position": 1} responses: "200": - application/json: {"metadata_field_id": "smd-field-1", "name": "My Rule", "condition": {"metadata_field_id": "smd-field-2", "populated": true}, "result": {"apply_value": {"value": "my value", "mode": "default"}}, "state": "active", "position": 1, "external_id": "1234567890", "condition_signature": "dGhlIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2c"} + application/json: {"metadata_field_id": "smd-field-1", "name": "Disable field when other field is populated", "condition": {"metadata_field_id": "smd-field-2", "populated": true}, "result": {}, "state": "active", "position": 1, "external_id": "1234567890", "condition_signature": "dGhlIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2c"} "400": application/json: {"error": {"message": ""}} listMetadataRules: @@ -721,10 +713,10 @@ examples: external_id: "" cloud_name: "" requestBody: - application/json: {"metadata_field_id": "smd-field-1", "name": "My Rule", "condition": {"metadata_field_id": "smd-field-2", "populated": true}, "result": {"apply_value": {"value": "my value", "mode": "default"}}, "state": "active", "position": 1} + application/json: {"metadata_field_id": "smd-field-1", "name": "Disable field when other field is populated", "condition": {"metadata_field_id": "smd-field-2", "populated": true}, "result": {}, "state": "active", "position": 1} responses: "200": - application/json: {"metadata_field_id": "smd-field-1", "name": "My Rule", "condition": {"metadata_field_id": "smd-field-2", "populated": true}, "result": {"apply_value": {"value": "my value", "mode": "default"}}, "state": "active", "position": 1, "external_id": "1234567890", "condition_signature": "dGhlIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2c"} + application/json: {"metadata_field_id": "smd-field-1", "name": "Disable field when other field is populated", "condition": {"metadata_field_id": "smd-field-2", "populated": true}, "result": {}, "state": "active", "position": 1, "external_id": "1234567890", "condition_signature": "dGhlIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2c"} "400": application/json: {"error": {"message": ""}} deleteMetadataRule: @@ -739,7 +731,7 @@ examples: "400": application/json: {"error": {"message": ""}} examplesVersion: 1.0.2 -releaseNotes: "## Mcp-typescript SDK Changes:\n* `CloudinarySMD.metadata_fields.createMetadataField()`: \n * `request.validation` **Changed** (Breaking ⚠️)\n * `response` **Changed** (Breaking ⚠️)\n* `CloudinarySMD.metadata_fields.listMetadataFields()`: `response.metadata_fields[]` **Changed** (Breaking ⚠️)\n* `CloudinarySMD.metadata_fields.getMetadataField()`: `response` **Changed** (Breaking ⚠️)\n* `CloudinarySMD.metadata_fields.updateMetadataField()`: \n * `request.metadata_field` **Changed** (Breaking ⚠️)\n * `response` **Changed** (Breaking ⚠️)\n* `CloudinarySMD.metadata_fields.updateMetadataFieldDatasource()`: `request` **Changed** (Breaking ⚠️)\n* `CloudinarySMD.metadata_fields.deleteMetadataFieldDatasource()`: `request` **Changed** (Breaking ⚠️)\n" +releaseNotes: "## Mcp-typescript SDK Changes:\n* `CloudinarySMD.metadata_fields.createMetadataField()`: \n * `request` **Changed**\n * `response` **Changed**\n* `CloudinarySMD.metadata_fields.listMetadataFields()`: `response.metadata_fields[]` **Changed**\n* `CloudinarySMD.metadata_fields.getMetadataField()`: `response` **Changed**\n* `CloudinarySMD.metadata_fields.updateMetadataField()`: \n * `request.metadata_field` **Changed**\n * `response` **Changed**\n" generatedFiles: - .dxtignore - .gitattributes diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index e29d55b..ecb189c 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -31,7 +31,7 @@ generation: generateNewTests: true skipResponseBodyAssertions: false mcp-typescript: - version: 0.5.0 + version: 0.6.0 additionalDependencies: dependencies: {} devDependencies: {} diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 24ae071..27c703b 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -1,18 +1,18 @@ -speakeasyVersion: 1.761.10 +speakeasyVersion: 1.789.1 sources: CloudinarySMD-MCP-OAS: sourceNamespace: cloudinary-structured-metadata-mcp-oas - sourceRevisionDigest: sha256:85c63199be6e15b3d6b3d16a16e2c33690a4dc147f2e48dc453b20a5fbf5ec43 - sourceBlobDigest: sha256:eb5e17fde26cf563d32221dfa8dc025a27f13caf100005f1871c0891263f45e8 + sourceRevisionDigest: sha256:100a218d96e6f4ff65d669e52b204abb0a157e75a948a8aa4e0c432b70c435bc + sourceBlobDigest: sha256:2090fcbd214524692bd0f0ae9e58a46541d739dbc63f17c5fba6b4bd357fbd37 tags: - latest - - 0.5.0 + - 0.5.5 targets: cloudinary-structured-metadata-mcp: source: CloudinarySMD-MCP-OAS sourceNamespace: cloudinary-structured-metadata-mcp-oas - sourceRevisionDigest: sha256:85c63199be6e15b3d6b3d16a16e2c33690a4dc147f2e48dc453b20a5fbf5ec43 - sourceBlobDigest: sha256:eb5e17fde26cf563d32221dfa8dc025a27f13caf100005f1871c0891263f45e8 + sourceRevisionDigest: sha256:100a218d96e6f4ff65d669e52b204abb0a157e75a948a8aa4e0c432b70c435bc + sourceBlobDigest: sha256:2090fcbd214524692bd0f0ae9e58a46541d739dbc63f17c5fba6b4bd357fbd37 workflow: workflowVersion: 1.0.0 speakeasyVersion: latest diff --git a/README.md b/README.md index 0b5a8e3..90200e4 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,9 @@
Claude Desktop -Install the MCP server as a Desktop Extension using the pre-built [`mcp-server.mcpb`](https://github.com/cloudinary/structured-metadata-mcp/releases/download/v0.5.0/mcp-server.mcpb) file: +Install the MCP server as a Desktop Extension using the pre-built [`mcp-server.mcpb`](https://github.com/cloudinary/structured-metadata-mcp/releases/download/v0.6.0/mcp-server.mcpb) file: -Simply drag and drop the [`mcp-server.mcpb`](https://github.com/cloudinary/structured-metadata-mcp/releases/download/v0.5.0/mcp-server.mcpb) file onto Claude Desktop to install the extension. +Simply drag and drop the [`mcp-server.mcpb`](https://github.com/cloudinary/structured-metadata-mcp/releases/download/v0.6.0/mcp-server.mcpb) file onto Claude Desktop to install the extension. The MCP bundle package includes the MCP server and all necessary configuration. Once installed, the server will be available without additional setup. diff --git a/RELEASES.md b/RELEASES.md index 6a92089..1684c5a 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -22,4 +22,12 @@ Based on: - OpenAPI Doc - Speakeasy CLI 1.761.10 (2.881.16) https://github.com/speakeasy-api/speakeasy ### Generated -- [mcp-typescript v0.5.0] . \ No newline at end of file +- [mcp-typescript v0.5.0] . + +## 2026-07-10 00:23:19 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.789.1 (2.916.4) https://github.com/speakeasy-api/speakeasy +### Generated +- [mcp-typescript v0.6.0] . \ No newline at end of file diff --git a/manifest.json b/manifest.json index ff8cb40..e977d13 100644 --- a/manifest.json +++ b/manifest.json @@ -69,7 +69,7 @@ "type": "string" } }, - "version": "0.5.0", + "version": "0.6.0", "tools": [ { "name": "create-metadata-field", diff --git a/package-lock.json b/package-lock.json index ab85960..e93ae92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cloudinary/structured-metadata-mcp", - "version": "0.5.0", + "version": "0.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cloudinary/structured-metadata-mcp", - "version": "0.5.0", + "version": "0.6.0", "dependencies": { "@modelcontextprotocol/sdk": "1.26.0", "@stricli/core": "^1.1.2", @@ -1995,9 +1995,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.1.0.tgz", + "integrity": "sha512-ZodJ2cRiLVWGi9IgPb3mbgSqM4CD3LexCHkuv0FfBXHJI1ADfucTD06m6clO2Cy5RZYsw/SiCVl/dyrFI/SYWA==", "funding": [ { "type": "github", @@ -2298,9 +2298,9 @@ } }, "node_modules/hono": { - "version": "4.12.8", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.8.tgz", - "integrity": "sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==", + "version": "4.12.28", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.28.tgz", + "integrity": "sha512-YwUvVpSF7m1yOblFPrU3Hbo8XhPheBoiyfGuII6z19LnOr6JpDnyyp7LFNrfV56wS8tpvtBFGRISHN02pDdLOA==", "license": "MIT", "engines": { "node": ">=16.9.0" diff --git a/package.json b/package.json index 8444854..9e68f27 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cloudinary/structured-metadata-mcp", - "version": "0.5.0", + "version": "0.6.0", "author": "Cloudinary", "type": "module", "sideEffects": false, @@ -26,7 +26,9 @@ "zod": "^4.0.0" }, "overrides": { - "@modelcontextprotocol/sdk": "1.26.0" + "@modelcontextprotocol/sdk": "1.26.0", + "hono": ">=4.12.25", + "fast-uri": ">=3.1.2" }, "devDependencies": { "@anthropic-ai/mcpb": "^1.2.0", diff --git a/src/landing-page.ts b/src/landing-page.ts index d6c164d..803a260 100644 --- a/src/landing-page.ts +++ b/src/landing-page.ts @@ -938,7 +938,7 @@ http_headers = { "api-key" = "YOUR_API_KEY", "api-secret" = "YOUR_API_SECRET", "

Instructions

One-click installation for Claude Desktop users

diff --git a/src/lib/config.ts b/src/lib/config.ts index 81816e8..fecbf08 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -111,9 +111,9 @@ export function serverURLFromOptions(options: SDKOptions): URL | null { export const SDK_METADATA = { language: "typescript", - openapiDocVersion: "0.5.0", - sdkVersion: "0.5.0", - genVersion: "2.881.16", + openapiDocVersion: "0.5.5", + sdkVersion: "0.6.0", + genVersion: "2.916.4", userAgent: - "speakeasy-sdk/mcp-typescript 0.5.0 2.881.16 0.5.0 @cloudinary/structured-metadata-mcp", + "speakeasy-sdk/mcp-typescript 0.6.0 2.916.4 0.5.5 @cloudinary/structured-metadata-mcp", } as const; diff --git a/src/lib/dlv.ts b/src/lib/dlv.ts deleted file mode 100644 index e81091f..0000000 --- a/src/lib/dlv.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. - */ - -/* -MIT License - -Copyright (c) 2024 Jason Miller (http://jasonformat.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -/** - * @param obj The object to walk - * @param key The key path to walk the object with - * @param def A default value to return if the result is undefined - * - * @example - * dlv(obj, "a.b.c.d") - * @example - * dlv(object, ["a", "b", "c", "d"]) - * @example - * dlv(object, "foo.bar.baz", "Hello, default value!") - */ -export function dlv( - obj: any, - key: string | string[], - def?: T, - p?: number, - undef?: never, -): T | undefined { - key = Array.isArray(key) ? key : key.split("."); - for (p = 0; p < key.length; p++) { - const k = key[p]; - obj = k != null && obj ? obj[k] : undef; - } - return obj === undef ? def : obj; -} diff --git a/src/lib/encodings.ts b/src/lib/encodings.ts index caa16bb..b19d1d0 100644 --- a/src/lib/encodings.ts +++ b/src/lib/encodings.ts @@ -3,7 +3,7 @@ */ import { bytesToBase64 } from "./base64.js"; -import { isPlainObject } from "./is-plain-object.js"; +import { isPlainObject } from "./primitives.js"; export class EncodingError extends Error { constructor(message: string) { diff --git a/src/lib/env.ts b/src/lib/env.ts index 40c8651..6f2ee7c 100644 --- a/src/lib/env.ts +++ b/src/lib/env.ts @@ -2,8 +2,6 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ -import { dlv } from "./dlv.js"; - import * as z from "zod"; import { SDKOptions } from "./config.js"; @@ -39,8 +37,13 @@ export function env(): Env { return envMemo; } + const globals = globalThis as { + process?: { env?: Record }; + Deno?: { env?: { toObject?: () => Record } }; + }; + envMemo = envSchema.parse( - dlv(globalThis, "process.env") ?? dlv(globalThis, "Deno.env") ?? {}, + globals.process?.env ?? globals.Deno?.env?.toObject?.() ?? {}, ); return envMemo; } diff --git a/src/lib/http.ts b/src/lib/http.ts index 13cf1fd..6b7a6cf 100644 --- a/src/lib/http.ts +++ b/src/lib/http.ts @@ -45,8 +45,10 @@ export class HTTPClient { private requestHooks: BeforeRequestHook[] = []; private requestErrorHooks: RequestErrorHook[] = []; private responseHooks: ResponseHook[] = []; + private options: HTTPClientOptions; - constructor(private options: HTTPClientOptions = {}) { + constructor(options: HTTPClientOptions = {}) { + this.options = options; this.fetcher = options.fetcher || DEFAULT_FETCHER; } diff --git a/src/lib/is-plain-object.ts b/src/lib/is-plain-object.ts deleted file mode 100644 index 61070d3..0000000 --- a/src/lib/is-plain-object.ts +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. - */ - -/* -MIT License - -Copyright (c) Sindre Sorhus (https://sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -// Taken from https://github.com/sindresorhus/is-plain-obj/blob/97f38e8836f86a642cce98fc6ab3058bc36df181/index.js - -export function isPlainObject(value: unknown): value is object { - if (typeof value !== "object" || value === null) { - return false; - } - - const prototype = Object.getPrototypeOf(value); - return ( - (prototype === null || - prototype === Object.prototype || - Object.getPrototypeOf(prototype) === null) && - !(Symbol.toStringTag in value) && - !(Symbol.iterator in value) - ); -} diff --git a/src/lib/primitives.ts b/src/lib/primitives.ts index 668ab9d..13567e7 100644 --- a/src/lib/primitives.ts +++ b/src/lib/primitives.ts @@ -111,3 +111,19 @@ export function invariant( throw new InvariantError(message); } } + +export function isPlainObject( + value: unknown, +): value is Record { + if (value === null || typeof value !== "object") return false; + if (Object.prototype.toString.call(value) !== "[object Object]") return false; + const proto = Object.getPrototypeOf(value); + if (proto === null || proto === Object.prototype) return true; + // cross-realm plain objects (vm contexts, iframes) inherit from a + // different realm's Object.prototype, which itself has a null prototype + try { + return Object.getPrototypeOf(proto) === null; + } catch { + return false; + } +} diff --git a/src/lib/retries.ts b/src/lib/retries.ts index e3ce9ab..21a647e 100644 --- a/src/lib/retries.ts +++ b/src/lib/retries.ts @@ -194,6 +194,14 @@ async function retryBackoff( } function retryIntervalFromResponse(res: Response): number { + const retryAfterMsVal = res.headers.get("retry-after-ms"); + if (retryAfterMsVal) { + const parsedMs = Number(retryAfterMsVal); + if (Number.isFinite(parsedMs) && parsedMs >= 0) { + return parsedMs; + } + } + const retryVal = res.headers.get("retry-after") || ""; if (!retryVal) { return 0; diff --git a/src/lib/security.ts b/src/lib/security.ts index ba1aef1..4baf554 100644 --- a/src/lib/security.ts +++ b/src/lib/security.ts @@ -13,17 +13,22 @@ type OAuth2PasswordFlow = { tokenURL: string; }; -export enum SecurityErrorCode { - Incomplete = "incomplete", - UnrecognisedSecurityType = "unrecognized_security_type", -} +export const SecurityErrorCode = { + Incomplete: "incomplete", + UnrecognisedSecurityType: "unrecognized_security_type", +} as const; +export type SecurityErrorCode = + (typeof SecurityErrorCode)[keyof typeof SecurityErrorCode]; export class SecurityError extends Error { + public code: SecurityErrorCode; + constructor( - public code: SecurityErrorCode, + code: SecurityErrorCode, message: string, ) { super(message); + this.code = code; this.name = "SecurityError"; } diff --git a/src/mcp-server/mcp-server.ts b/src/mcp-server/mcp-server.ts index d4af9d4..68d8c1c 100644 --- a/src/mcp-server/mcp-server.ts +++ b/src/mcp-server/mcp-server.ts @@ -21,7 +21,7 @@ const routes = buildRouteMap({ export const app = buildApplication(routes, { name: "mcp", versionInfo: { - currentVersion: "0.5.0", + currentVersion: "0.6.0", }, }); diff --git a/src/mcp-server/server.ts b/src/mcp-server/server.ts index 7be0d25..2c18887 100644 --- a/src/mcp-server/server.ts +++ b/src/mcp-server/server.ts @@ -45,7 +45,7 @@ export function createMCPServer(deps: { }) { const server = new McpServer({ name: "CloudinarySMD", - version: "0.5.0", + version: "0.6.0", }); const getClient = deps.getSDK || (() => diff --git a/src/mcp-server/tools.ts b/src/mcp-server/tools.ts index df74973..c5158f1 100644 --- a/src/mcp-server/tools.ts +++ b/src/mcp-server/tools.ts @@ -344,6 +344,8 @@ export function registerDynamicTools( if (def.args) { const jsonSchema = z.toJSONSchema(z.object(def.args), { target: "draft-2020-12", + io: "input", + unrepresentable: "any", }); schemaText += JSON.stringify(jsonSchema, null, 2); } else { diff --git a/src/models/createmetadatafieldop.ts b/src/models/createmetadatafieldop.ts index ade6697..f256438 100644 --- a/src/models/createmetadatafieldop.ts +++ b/src/models/createmetadatafieldop.ts @@ -55,19 +55,31 @@ export const CreateMetadataFieldDefaultValue$zodSchema: z.ZodType< ]).describe("The default value of the metadata field."); /** - * The restrictions defined for the metadata field. + * Controls UI visibility and editability of the field. All three keys are always returned; any omitted key on input defaults to false. + * + * @remarks */ export type CreateMetadataFieldRestrictions = { readonly_ui?: boolean | undefined; + hidden_ui?: boolean | undefined; + excluded_from_search?: boolean | undefined; }; export const CreateMetadataFieldRestrictions$zodSchema: z.ZodType< CreateMetadataFieldRestrictions > = z.object({ + excluded_from_search: z.boolean().optional().describe( + "Whether the field is excluded from UI search by default.", + ), + hidden_ui: z.boolean().optional().describe( + "Whether the field is hidden in the UI by default.", + ), readonly_ui: z.boolean().optional().describe( - "Whether the metadata field is read-only in the UI. when true, the metadata field can only be updated via the API.", + "Whether the field is read-only in the UI. When true, the field can only be updated via the API.", ), -}).describe("The restrictions defined for the metadata field."); +}).describe( + "Controls UI visibility and editability of the field. All three keys are always returned; any omitted key on input defaults to false.\n", +); export type CreateMetadataFieldValue = { external_id?: string | undefined; @@ -114,6 +126,7 @@ export type CreateMetadataFieldRequest = { restrictions?: CreateMetadataFieldRestrictions | null | undefined; datasource?: CreateMetadataFieldDatasource | null | undefined; allow_dynamic_list_values?: boolean | null | undefined; + alphabetically_sorted?: boolean | undefined; }; export const CreateMetadataFieldRequest$zodSchema: z.ZodType< @@ -122,10 +135,13 @@ export const CreateMetadataFieldRequest$zodSchema: z.ZodType< allow_dynamic_list_values: z.boolean().nullable().optional().describe( "Whether the metadata field allows adding new options to the datasource dynamically.", ), + alphabetically_sorted: z.boolean().optional().describe( + "Whether datasource values are maintained in case-insensitive alphabetical order. When true, values are automatically sorted on insert and update. Default false.", + ), datasource: z.lazy(() => CreateMetadataFieldDatasource$zodSchema).nullable() .optional().describe("The datasource defined for the metadata field."), default_disabled: z.boolean().nullable().optional().describe( - "Whether the default value is disabled.", + "Whether the field is disabled in the UI by default.", ), default_value: z.union([ z.string(), @@ -140,7 +156,7 @@ export const CreateMetadataFieldRequest$zodSchema: z.ZodType< ), restrictions: z.lazy(() => CreateMetadataFieldRestrictions$zodSchema) .nullable().optional().describe( - "The restrictions defined for the metadata field.", + "Controls UI visibility and editability of the field. All three keys are always returned; any omitted key on input defaults to false.\n", ), type: CreateMetadataFieldType$zodSchema.describe( "The type of the metadata field.", diff --git a/src/models/metadatafield.ts b/src/models/metadatafield.ts index ddda27a..e0b8a4e 100644 --- a/src/models/metadatafield.ts +++ b/src/models/metadatafield.ts @@ -40,15 +40,29 @@ export const DefaultValue$zodSchema: z.ZodType = z.union([ ]).describe("The default value of the metadata field."); /** - * The restrictions defined for the metadata field. + * Controls UI visibility and editability of the field. All three keys are always returned; any omitted key on input defaults to false. + * + * @remarks */ -export type Restrictions = { readonly_ui?: boolean | undefined }; +export type Restrictions = { + readonly_ui?: boolean | undefined; + hidden_ui?: boolean | undefined; + excluded_from_search?: boolean | undefined; +}; export const Restrictions$zodSchema: z.ZodType = z.object({ + excluded_from_search: z.boolean().optional().describe( + "Whether the field is excluded from UI search by default.", + ), + hidden_ui: z.boolean().optional().describe( + "Whether the field is hidden in the UI by default.", + ), readonly_ui: z.boolean().optional().describe( - "Whether the metadata field is read-only in the UI. when true, the metadata field can only be updated via the API.", + "Whether the field is read-only in the UI. When true, the field can only be updated via the API.", ), -}).describe("The restrictions defined for the metadata field."); +}).describe( + "Controls UI visibility and editability of the field. All three keys are always returned; any omitted key on input defaults to false.\n", +); export type MetadataFieldValue = { external_id?: string | undefined; @@ -89,17 +103,21 @@ export type MetadataField = { restrictions?: Restrictions | null | undefined; datasource?: Datasource | null | undefined; allow_dynamic_list_values?: boolean | null | undefined; + alphabetically_sorted?: boolean | undefined; }; export const MetadataField$zodSchema: z.ZodType = z.object({ allow_dynamic_list_values: z.boolean().nullable().optional().describe( "Whether the metadata field allows adding new options to the datasource dynamically.", ), + alphabetically_sorted: z.boolean().optional().describe( + "Whether datasource values are maintained in case-insensitive alphabetical order. When true, values are automatically sorted on insert and update. Default false.", + ), datasource: z.lazy(() => Datasource$zodSchema).nullable().optional().describe( "The datasource defined for the metadata field.", ), default_disabled: z.boolean().nullable().optional().describe( - "Whether the default value is disabled.", + "Whether the field is disabled in the UI by default.", ), default_value: z.union([ z.string(), @@ -113,7 +131,9 @@ export const MetadataField$zodSchema: z.ZodType = z.object({ "Whether the metadata field is mandatory.", ), restrictions: z.lazy(() => Restrictions$zodSchema).nullable().optional() - .describe("The restrictions defined for the metadata field."), + .describe( + "Controls UI visibility and editability of the field. All three keys are always returned; any omitted key on input defaults to false.\n", + ), type: Type$zodSchema.optional().describe("The type of the metadata field."), validation: z.record(z.string(), z.any()).nullable().optional().describe( "The validation defined for the metadata field.", diff --git a/src/types/async.ts b/src/types/async.ts index 689dba5..1543b95 100644 --- a/src/types/async.ts +++ b/src/types/async.ts @@ -21,16 +21,17 @@ export type APICall = export class APIPromise implements Promise { readonly #promise: Promise<[T, APICall]>; - readonly #unwrapped: Promise; + #unwrapped: Promise | null; readonly [Symbol.toStringTag] = "APIPromise"; constructor(p: [T, APICall] | Promise<[T, APICall]>) { this.#promise = p instanceof Promise ? p : Promise.resolve(p); - this.#unwrapped = - p instanceof Promise - ? this.#promise.then(([value]) => value) - : Promise.resolve(p[0]); + this.#unwrapped = p instanceof Promise ? null : Promise.resolve(p[0]); + } + + #getUnwrapped(): Promise { + return (this.#unwrapped ??= this.#promise.then(([value]) => value)); } then( @@ -55,11 +56,11 @@ export class APIPromise implements Promise { | null | undefined, ): Promise { - return this.#unwrapped.catch(onrejected); + return this.#getUnwrapped().catch(onrejected); } finally(onfinally?: (() => void) | null | undefined): Promise { - return this.#unwrapped.finally(onfinally); + return this.#getUnwrapped().finally(onfinally); } $inspect(): Promise<[T, APICall]> { diff --git a/src/types/bigint.ts b/src/types/bigint.ts index f32ee5f..91c22c4 100644 --- a/src/types/bigint.ts +++ b/src/types/bigint.ts @@ -24,23 +24,24 @@ export function bigint(): z.ZodType { } export function bigintOptional(): z.ZodType { - return z.union([ - z.bigint().transform((v) => String(v)), - z.string().transform((v, ctx) => { - try { - return BigInt(v); - } catch { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "Invalid bigint value", - }); - return z.NEVER; - } - }), - z.number().transform((v) => BigInt(Math.trunc(v))), - z.undefined(), - z.null().transform(() => undefined), - ]); + return z + .union([ + z.bigint().transform((v) => String(v)), + z.string().transform((v, ctx) => { + try { + return BigInt(v); + } catch { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "Invalid bigint value", + }); + return z.NEVER; + } + }), + z.number().transform((v) => BigInt(Math.trunc(v))), + z.null().transform(() => undefined), + ]) + .optional(); } export function bigintNullable(): z.ZodType {