@anyproto/anytype-mcp 1.0.7 → 1.0.8

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/server.json CHANGED
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "environment_variables": [
21
21
  {
22
- "description": "JSON string of headers for Anytype API. Example: {\"Authorization\":\"Bearer <YOUR_API_KEY>\", \"Anytype-Version\":\"2025-05-20\"}",
22
+ "description": "JSON string of headers for Anytype API. Example: {\"Authorization\":\"Bearer <YOUR_API_KEY>\", \"Anytype-Version\":\"2025-11-08\"}",
23
23
  "is_required": true,
24
24
  "format": "string",
25
25
  "is_secret": true,
@@ -5,16 +5,19 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
5
  import { HttpClient } from "../http-client";
6
6
 
7
7
  // Mock the OpenAPIClientAxios initialization
8
+ const mockApi = {
9
+ getPet: vi.fn(),
10
+ testOperation: vi.fn(),
11
+ complexOperation: vi.fn(),
12
+ };
13
+
8
14
  vi.mock("openapi-client-axios", () => {
9
- const mockApi = {
10
- getPet: vi.fn(),
11
- testOperation: vi.fn(),
12
- complexOperation: vi.fn(),
13
- };
15
+ const MockOpenAPIClientAxios = vi.fn(function (this: any) {
16
+ this.init = vi.fn().mockResolvedValue(mockApi);
17
+ return this;
18
+ });
14
19
  return {
15
- default: vi.fn().mockImplementation(() => ({
16
- init: vi.fn().mockResolvedValue(mockApi),
17
- })),
20
+ default: MockOpenAPIClientAxios,
18
21
  };
19
22
  });
20
23
 
@@ -473,12 +476,13 @@ describe("HttpClient", () => {
473
476
  testOperation: vi.fn().mockRejectedValue(errorResponse),
474
477
  };
475
478
 
476
- // Mock the OpenAPIClientAxios initialization
477
- const MockOpenAPIClientAxios = vi.fn().mockImplementation(() => ({
478
- init: () => Promise.resolve(mockAxiosInstance),
479
- }));
479
+ // Mock the OpenAPIClientAxios initialization - use function keyword for constructor support
480
+ const MockOpenAPIClientAxios = vi.fn(function (this: any) {
481
+ this.init = vi.fn().mockResolvedValue(mockAxiosInstance);
482
+ return this;
483
+ });
480
484
 
481
- vi.mocked(OpenAPIClientAxios).mockImplementation(() => MockOpenAPIClientAxios());
485
+ vi.mocked(OpenAPIClientAxios).mockImplementation(MockOpenAPIClientAxios as any);
482
486
 
483
487
  const client = new HttpClient(mockConfig, mockOpenApiSpec);
484
488
  const operation = mockOpenApiSpec.paths["/test"]?.post;
@@ -510,11 +514,13 @@ describe("HttpClient", () => {
510
514
  }),
511
515
  };
512
516
 
513
- const MockOpenAPIClientAxios = vi.fn().mockImplementation(() => ({
514
- init: () => Promise.resolve(mockAxiosInstance),
515
- }));
517
+ // Mock the OpenAPIClientAxios initialization - use function keyword for constructor support
518
+ const MockOpenAPIClientAxios = vi.fn(function (this: any) {
519
+ this.init = vi.fn().mockResolvedValue(mockAxiosInstance);
520
+ return this;
521
+ });
516
522
 
517
- vi.mocked(OpenAPIClientAxios).mockImplementation(() => MockOpenAPIClientAxios());
523
+ vi.mocked(OpenAPIClientAxios).mockImplementation(MockOpenAPIClientAxios as any);
518
524
 
519
525
  const client = new HttpClient(mockConfig, mockOpenApiSpec);
520
526
  const operation = mockOpenApiSpec.paths["/test"]?.post;
@@ -855,6 +855,142 @@ describe("OpenAPIToMCPConverter", () => {
855
855
  description: "A schema description",
856
856
  });
857
857
  });
858
+
859
+ describe("Delete Operations Support", () => {
860
+ const deleteSpec: OpenAPIV3.Document = {
861
+ openapi: "3.0.0",
862
+ info: {
863
+ title: "Delete Test API",
864
+ version: "1.0.0",
865
+ },
866
+ paths: {
867
+ "/objects/{object_id}": {
868
+ delete: {
869
+ operationId: "delete_object",
870
+ summary: "Delete an object",
871
+ parameters: [
872
+ {
873
+ name: "object_id",
874
+ in: "path",
875
+ required: true,
876
+ description: "The ID of the object to delete",
877
+ schema: {
878
+ type: "string",
879
+ },
880
+ },
881
+ ],
882
+ responses: {
883
+ "200": {
884
+ description: "Object deleted successfully",
885
+ content: {
886
+ "application/json": {
887
+ schema: {
888
+ type: "object",
889
+ properties: {
890
+ id: { type: "string" },
891
+ deleted: { type: "boolean" },
892
+ },
893
+ },
894
+ },
895
+ },
896
+ },
897
+ },
898
+ },
899
+ },
900
+ "/lists/{list_id}/objects/{object_id}": {
901
+ delete: {
902
+ operationId: "remove_list_object",
903
+ summary: "Remove object from list",
904
+ parameters: [
905
+ {
906
+ name: "list_id",
907
+ in: "path",
908
+ required: true,
909
+ description: "The ID of the list",
910
+ schema: { type: "string" },
911
+ },
912
+ {
913
+ name: "object_id",
914
+ in: "path",
915
+ required: true,
916
+ description: "The ID of the object to remove",
917
+ schema: { type: "string" },
918
+ },
919
+ ],
920
+ responses: {
921
+ "200": {
922
+ description: "Object removed from list",
923
+ content: {
924
+ "application/json": {
925
+ schema: {
926
+ type: "object",
927
+ properties: {
928
+ success: { type: "boolean" },
929
+ },
930
+ },
931
+ },
932
+ },
933
+ },
934
+ },
935
+ },
936
+ },
937
+ },
938
+ };
939
+
940
+ it("should include delete operations in MCP tools", () => {
941
+ const converter = new OpenAPIToMCPConverter(deleteSpec);
942
+ const { tools, openApiLookup } = converter.convertToMCPTools();
943
+
944
+ expect(tools).toHaveProperty("API");
945
+ expect(tools.API.methods).toHaveLength(2);
946
+
947
+ const deleteObjectMethod = tools.API.methods.find((m) => m.name === "delete-object");
948
+ const removeListObjectMethod = tools.API.methods.find((m) => m.name === "remove-list-object");
949
+
950
+ expect(deleteObjectMethod).toBeDefined();
951
+ expect(removeListObjectMethod).toBeDefined();
952
+
953
+ // Check that delete operations are in the lookup
954
+ expect(openApiLookup).toHaveProperty("API-delete-object");
955
+ expect(openApiLookup).toHaveProperty("API-remove-list-object");
956
+
957
+ // Verify delete object method parameters
958
+ const deleteParams = getParamsFromSchema(deleteObjectMethod!);
959
+ expect(deleteParams).toContainEqual({
960
+ name: "object_id",
961
+ type: "string",
962
+ description: "The ID of the object to delete",
963
+ optional: false,
964
+ });
965
+
966
+ // Verify remove list object method parameters
967
+ const removeParams = getParamsFromSchema(removeListObjectMethod!);
968
+ expect(removeParams).toEqual(
969
+ expect.arrayContaining([
970
+ expect.objectContaining({
971
+ name: "list_id",
972
+ type: "string",
973
+ description: "The ID of the list",
974
+ optional: false,
975
+ }),
976
+ expect.objectContaining({
977
+ name: "object_id",
978
+ type: "string",
979
+ description: "The ID of the object to remove",
980
+ optional: false,
981
+ }),
982
+ ]),
983
+ );
984
+ });
985
+
986
+ it("should handle delete operations with proper error responses", () => {
987
+ const converter = new OpenAPIToMCPConverter(deleteSpec);
988
+ const { tools } = converter.convertToMCPTools();
989
+
990
+ const deleteObjectMethod = tools.API.methods.find((m) => m.name === "delete-object");
991
+ expect(deleteObjectMethod?.description).toContain("Delete an object");
992
+ });
993
+ });
858
994
  });
859
995
 
860
996
  // Additional complex test scenarios as a table test
@@ -327,13 +327,8 @@ export class OpenAPIToMCPConverter {
327
327
  if (!pathItem) continue;
328
328
 
329
329
  for (const [method, operation] of Object.entries(pathItem)) {
330
- // skip "Auth" operations and delete operations, as they shouldn't be called by mcp client
331
- if (
332
- !this.isOperation(method, operation) ||
333
- operation.tags?.includes("Auth") ||
334
- method.toLowerCase() === "delete"
335
- )
336
- continue;
330
+ // skip "Auth" operations, as they shouldn't be called by mcp client
331
+ if (!this.isOperation(method, operation) || operation.tags?.includes("Auth")) continue;
337
332
 
338
333
  const mcpMethod = this.convertOperationToMCPMethod(operation, method, path);
339
334
  if (mcpMethod) {
@@ -360,13 +355,8 @@ export class OpenAPIToMCPConverter {
360
355
  if (!pathItem) continue;
361
356
 
362
357
  for (const [method, operation] of Object.entries(pathItem)) {
363
- // skip "Auth" operations and delete operations, as they shouldn't be called by mcp client
364
- if (
365
- !this.isOperation(method, operation) ||
366
- operation.tags?.includes("Auth") ||
367
- method.toLowerCase() === "delete"
368
- )
369
- continue;
358
+ // skip "Auth" operations, as they shouldn't be called by mcp client
359
+ if (!this.isOperation(method, operation) || operation.tags?.includes("Auth")) continue;
370
360
 
371
361
  const parameters = this.convertOperationToJsonSchema(operation, method, path);
372
362
  const tool: ChatCompletionTool = {
@@ -394,13 +384,8 @@ export class OpenAPIToMCPConverter {
394
384
  if (!pathItem) continue;
395
385
 
396
386
  for (const [method, operation] of Object.entries(pathItem)) {
397
- // skip "Auth" operations and delete operations, as they shouldn't be called by mcp client
398
- if (
399
- !this.isOperation(method, operation) ||
400
- operation.tags?.includes("Auth") ||
401
- method.toLowerCase() === "delete"
402
- )
403
- continue;
387
+ // skip "Auth" operations, as they shouldn't be called by mcp client
388
+ if (!this.isOperation(method, operation) || operation.tags?.includes("Auth")) continue;
404
389
 
405
390
  const parameters = this.convertOperationToJsonSchema(operation, method, path);
406
391
  const tool: Tool = {