basic-memory 0.7.0__py3-none-any.whl → 0.9.0__py3-none-any.whl
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.
Potentially problematic release.
This version of basic-memory might be problematic. Click here for more details.
- basic_memory/__init__.py +1 -1
- basic_memory/alembic/alembic.ini +119 -0
- basic_memory/alembic/env.py +23 -1
- basic_memory/alembic/migrations.py +4 -9
- basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py +51 -0
- basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py +44 -0
- basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py +106 -0
- basic_memory/api/app.py +9 -10
- basic_memory/api/routers/__init__.py +2 -1
- basic_memory/api/routers/knowledge_router.py +31 -5
- basic_memory/api/routers/memory_router.py +18 -17
- basic_memory/api/routers/project_info_router.py +275 -0
- basic_memory/api/routers/resource_router.py +105 -4
- basic_memory/api/routers/search_router.py +22 -4
- basic_memory/cli/app.py +54 -5
- basic_memory/cli/commands/__init__.py +15 -2
- basic_memory/cli/commands/db.py +9 -13
- basic_memory/cli/commands/import_chatgpt.py +26 -30
- basic_memory/cli/commands/import_claude_conversations.py +27 -29
- basic_memory/cli/commands/import_claude_projects.py +29 -31
- basic_memory/cli/commands/import_memory_json.py +26 -28
- basic_memory/cli/commands/mcp.py +7 -1
- basic_memory/cli/commands/project.py +119 -0
- basic_memory/cli/commands/project_info.py +167 -0
- basic_memory/cli/commands/status.py +14 -28
- basic_memory/cli/commands/sync.py +63 -22
- basic_memory/cli/commands/tool.py +253 -0
- basic_memory/cli/main.py +39 -1
- basic_memory/config.py +166 -4
- basic_memory/db.py +19 -4
- basic_memory/deps.py +10 -3
- basic_memory/file_utils.py +37 -19
- basic_memory/markdown/entity_parser.py +3 -3
- basic_memory/markdown/utils.py +5 -0
- basic_memory/mcp/async_client.py +1 -1
- basic_memory/mcp/main.py +24 -0
- basic_memory/mcp/prompts/__init__.py +19 -0
- basic_memory/mcp/prompts/ai_assistant_guide.py +26 -0
- basic_memory/mcp/prompts/continue_conversation.py +111 -0
- basic_memory/mcp/prompts/recent_activity.py +88 -0
- basic_memory/mcp/prompts/search.py +182 -0
- basic_memory/mcp/prompts/utils.py +155 -0
- basic_memory/mcp/server.py +2 -6
- basic_memory/mcp/tools/__init__.py +12 -21
- basic_memory/mcp/tools/build_context.py +85 -0
- basic_memory/mcp/tools/canvas.py +97 -0
- basic_memory/mcp/tools/delete_note.py +28 -0
- basic_memory/mcp/tools/project_info.py +51 -0
- basic_memory/mcp/tools/read_content.py +229 -0
- basic_memory/mcp/tools/read_note.py +190 -0
- basic_memory/mcp/tools/recent_activity.py +100 -0
- basic_memory/mcp/tools/search.py +56 -17
- basic_memory/mcp/tools/utils.py +245 -16
- basic_memory/mcp/tools/write_note.py +124 -0
- basic_memory/models/knowledge.py +27 -11
- basic_memory/models/search.py +2 -1
- basic_memory/repository/entity_repository.py +3 -2
- basic_memory/repository/project_info_repository.py +9 -0
- basic_memory/repository/repository.py +24 -7
- basic_memory/repository/search_repository.py +47 -14
- basic_memory/schemas/__init__.py +10 -9
- basic_memory/schemas/base.py +4 -1
- basic_memory/schemas/memory.py +14 -4
- basic_memory/schemas/project_info.py +96 -0
- basic_memory/schemas/search.py +29 -33
- basic_memory/services/context_service.py +3 -3
- basic_memory/services/entity_service.py +26 -13
- basic_memory/services/file_service.py +145 -26
- basic_memory/services/link_resolver.py +9 -46
- basic_memory/services/search_service.py +95 -22
- basic_memory/sync/__init__.py +3 -2
- basic_memory/sync/sync_service.py +523 -117
- basic_memory/sync/watch_service.py +258 -132
- basic_memory/utils.py +51 -36
- basic_memory-0.9.0.dist-info/METADATA +736 -0
- basic_memory-0.9.0.dist-info/RECORD +99 -0
- basic_memory/alembic/README +0 -1
- basic_memory/cli/commands/tools.py +0 -157
- basic_memory/mcp/tools/knowledge.py +0 -68
- basic_memory/mcp/tools/memory.py +0 -170
- basic_memory/mcp/tools/notes.py +0 -202
- basic_memory/schemas/discovery.py +0 -28
- basic_memory/sync/file_change_scanner.py +0 -158
- basic_memory/sync/utils.py +0 -31
- basic_memory-0.7.0.dist-info/METADATA +0 -378
- basic_memory-0.7.0.dist-info/RECORD +0 -82
- {basic_memory-0.7.0.dist-info → basic_memory-0.9.0.dist-info}/WHEEL +0 -0
- {basic_memory-0.7.0.dist-info → basic_memory-0.9.0.dist-info}/entry_points.txt +0 -0
- {basic_memory-0.7.0.dist-info → basic_memory-0.9.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
basic_memory/__init__.py,sha256=0_LT1EXC7q97Yg06x_HyIbgFHRqZg8II59ADHFmFcrc,122
|
|
2
|
+
basic_memory/config.py,sha256=uJ3s5Hka7rKVMDhKXMJhtxdwZHPfSVape7a4ySkJhws,7644
|
|
3
|
+
basic_memory/db.py,sha256=UDWBr52u7oBT4aXputhAG_Prmsv5og00sYVzPmaylhk,6026
|
|
4
|
+
basic_memory/deps.py,sha256=yI6RL_5-8LXw7ywSJ_84BXAczDtv2h9GFLw-E9XDJFg,5770
|
|
5
|
+
basic_memory/file_utils.py,sha256=6pcqhBXSp7r_KogLWx8HUUaWCWdoIsSJnM7psD92f-c,6604
|
|
6
|
+
basic_memory/utils.py,sha256=EPumxT4HkprZG9BzWZnym3teOjn24Vm3lgncQADN5ew,3764
|
|
7
|
+
basic_memory/alembic/alembic.ini,sha256=IEZsnF8CbbZnkwBr67LzKKNobHuzTaQNUvM8Psop5xc,3733
|
|
8
|
+
basic_memory/alembic/env.py,sha256=GyQpEpQu84flqAdelxR0-H9nbkHrVoCboYGfmltBDoA,2737
|
|
9
|
+
basic_memory/alembic/migrations.py,sha256=lriHPXDdBLSNXEW3QTpU0SJKuVd1V-8NrVkpN3qfsUQ,718
|
|
10
|
+
basic_memory/alembic/script.py.mako,sha256=MEqL-2qATlST9TAOeYgscMn1uy6HUS9NFvDgl93dMj8,635
|
|
11
|
+
basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py,sha256=lTbWlAnd1es7xU99DoJgfaRe1_Kte8TL98riqeKGV80,4363
|
|
12
|
+
basic_memory/alembic/versions/502b60eaa905_remove_required_from_entity_permalink.py,sha256=k6xYTmYPM9Ros-7CA7BwZBKYwoK_gmVdC-2n8FAjdoE,1840
|
|
13
|
+
basic_memory/alembic/versions/b3c3938bacdb_relation_to_name_unique_index.py,sha256=RsGymQzfRXV1LSNKiyi0lMilTxW1NgwS9jR67ye2apI,1428
|
|
14
|
+
basic_memory/alembic/versions/cc7172b46608_update_search_index_schema.py,sha256=Lbo3dEzdId_vKRFe3jMkGFF3dNQpblPIQa4Bh7np-zA,4020
|
|
15
|
+
basic_memory/api/__init__.py,sha256=wCpj-21j1D0KzKl9Ql6unLBVFY0K1uGp_FeSZRKtqpk,72
|
|
16
|
+
basic_memory/api/app.py,sha256=NLcNpfNzVz4pgtbjaZUHTvRCqay16J_G4K1ok9DMDCU,1516
|
|
17
|
+
basic_memory/api/routers/__init__.py,sha256=SKuL-weA58hYj0NOMCQRfmsaumlNjjyVHDXNpRO38bQ,305
|
|
18
|
+
basic_memory/api/routers/knowledge_router.py,sha256=iYuBguMb6ERitAwoelSejBYJqLTGfjpkzAHrqwTKjVE,5876
|
|
19
|
+
basic_memory/api/routers/memory_router.py,sha256=W_uHJe2c4XN96mFj6XNvUH6INVbl1BMxy0KUchLcbxU,5421
|
|
20
|
+
basic_memory/api/routers/project_info_router.py,sha256=Heoz4mHaAeWQYDMsStk4fpwkVNmBlGh9XVbuJMpyGik,9015
|
|
21
|
+
basic_memory/api/routers/resource_router.py,sha256=WEJEqEaY_yTKj5-U-rW4kXQKUcJflykgwI6_g_R41ck,8058
|
|
22
|
+
basic_memory/api/routers/search_router.py,sha256=R_a5OF5_8rCjmoOMhmw3M4VLCy6I1KLGJ-otSLB0rbI,1953
|
|
23
|
+
basic_memory/cli/__init__.py,sha256=arcKLAWRDhPD7x5t80MlviZeYzwHZ0GZigyy3NKVoGk,33
|
|
24
|
+
basic_memory/cli/app.py,sha256=J4mkWnxbevOYmJwwRMx344olGOxoXq0o4RNG6DMQLKE,1804
|
|
25
|
+
basic_memory/cli/main.py,sha256=9uwxOUc4mDeTeZCEWyJh7X5PzPXG1fva2veV2OPbFtg,1442
|
|
26
|
+
basic_memory/cli/commands/__init__.py,sha256=aBihwtUFs0MpsxCed74A5fYoxFmJA4NOVXPRrVY4lnw,427
|
|
27
|
+
basic_memory/cli/commands/db.py,sha256=UL3JXGJrLzKZ-uRwgk6p0kbRznBy5x7keirvweVGNvY,754
|
|
28
|
+
basic_memory/cli/commands/import_chatgpt.py,sha256=bGKHz5pFD-oabaeeSqylHBcr9hnF4CzUqEIaFyRwpPE,8147
|
|
29
|
+
basic_memory/cli/commands/import_claude_conversations.py,sha256=Ba97fH5yfW642yrkxay3YkyDdgIYCeru-MUIZfEGblo,6812
|
|
30
|
+
basic_memory/cli/commands/import_claude_projects.py,sha256=GePfhEMstD97EIGoM8vJMmwDCnYfh1PjZH7DNcqzdqA,6634
|
|
31
|
+
basic_memory/cli/commands/import_memory_json.py,sha256=zqpU4eCzQXx04aRsigddJAyhvklmTgSAzeRTuEdNw0c,5194
|
|
32
|
+
basic_memory/cli/commands/mcp.py,sha256=ue_zDA8w0zZZToHLvu56s8hWkalgZsC64CfTyXX6z2I,715
|
|
33
|
+
basic_memory/cli/commands/project.py,sha256=vEPv34Grn8DGwP8Ig9xcFWeVW0cro_Qyfq2TU22pcQQ,4103
|
|
34
|
+
basic_memory/cli/commands/project_info.py,sha256=2XFe0eONsJ-FOmiOO6faYAS9AgX7Dmj4HNeTTrUr0ZE,7099
|
|
35
|
+
basic_memory/cli/commands/status.py,sha256=nbs3myxaNtehEEJ4BBngPuKs-vqZTHNCCb0bTgDsE-s,5277
|
|
36
|
+
basic_memory/cli/commands/sync.py,sha256=JxGJA6b7Qksz0ZKonHfB3s--7qzY7eWeLogPX8tR1pY,8351
|
|
37
|
+
basic_memory/cli/commands/tool.py,sha256=DjoB4slhmzfCjIgom1-xBP6sRl_gy7PrhGtQk3rNAqM,8855
|
|
38
|
+
basic_memory/markdown/__init__.py,sha256=DdzioCWtDnKaq05BHYLgL_78FawEHLpLXnp-kPSVfIc,501
|
|
39
|
+
basic_memory/markdown/entity_parser.py,sha256=LnjG_wg38LVN8JndsZJV2UVGPIaoIV5sGs94iQ9PL6k,3781
|
|
40
|
+
basic_memory/markdown/markdown_processor.py,sha256=mV3pYoDTaQMEl1tA5n_XztBvNlYyH2SzKs4vnKdAet4,4952
|
|
41
|
+
basic_memory/markdown/plugins.py,sha256=gtIzKRjoZsyvBqLpVNnrmzl_cbTZ5ZGn8kcuXxQjRko,6639
|
|
42
|
+
basic_memory/markdown/schemas.py,sha256=mzVEDUhH98kwETMknjkKw5H697vg_zUapsJkJVi17ho,1894
|
|
43
|
+
basic_memory/markdown/utils.py,sha256=zlHlUtrnXaUCnsaPNJzR0wlhg2kB1YbXx0DMvs-snJM,2973
|
|
44
|
+
basic_memory/mcp/__init__.py,sha256=dsDOhKqjYeIbCULbHIxfcItTbqudEuEg1Np86eq0GEQ,35
|
|
45
|
+
basic_memory/mcp/async_client.py,sha256=Eo345wANiBRSM4u3j_Vd6Ax4YtMg7qbWd9PIoFfj61I,236
|
|
46
|
+
basic_memory/mcp/main.py,sha256=0kbcyf1PxRC1bLnHv2zzParfJ6cOq7Am9ScF9UoI50U,703
|
|
47
|
+
basic_memory/mcp/server.py,sha256=VGv0uWma6JGkT6Y_GESYGhGMYfPavkhEKlCNza8bvtY,287
|
|
48
|
+
basic_memory/mcp/prompts/__init__.py,sha256=-Bl9Dgj2TD9PULjzggPqXuvPEjWCRy7S9Yg03h2-U7A,615
|
|
49
|
+
basic_memory/mcp/prompts/ai_assistant_guide.py,sha256=dgPdpC_WR88-ex4aMpAIC6TMZyZD3rgKyUu8qkSNIzw,824
|
|
50
|
+
basic_memory/mcp/prompts/continue_conversation.py,sha256=zb_3cOaO7NMFuStBkJDlMstQZqz1RCOYl6txwaHYM_Q,4424
|
|
51
|
+
basic_memory/mcp/prompts/recent_activity.py,sha256=7607MWiGJWY0vPurhVII17LxLZlXY_zmH3xH9LfT6SY,2793
|
|
52
|
+
basic_memory/mcp/prompts/search.py,sha256=nCz5wPxTszJLNQJ1CE7CIhnamy08EpGLQjoBMlXRRNc,6283
|
|
53
|
+
basic_memory/mcp/prompts/utils.py,sha256=u_bG8DMtMMERvGPJfA3gbl5VAs0xmkuK8ZJBkY8xyV8,5371
|
|
54
|
+
basic_memory/mcp/tools/__init__.py,sha256=mp8BiY-2YY5zzGBAIbf9hMCQM6uhDtst3eq1ApR2p2s,870
|
|
55
|
+
basic_memory/mcp/tools/build_context.py,sha256=8xYRPpeYCEU8F9Dv_ctvbunZ8ciKwmFu9i8Pdv5vYfI,2891
|
|
56
|
+
basic_memory/mcp/tools/canvas.py,sha256=fHC90eshnSSmROTBV-tBB-FSuXSpYVj_BcDrc96pWi0,2993
|
|
57
|
+
basic_memory/mcp/tools/delete_note.py,sha256=mnrgOv-D7f6nsgZIAK0Wvyn0dbkwCg8adW_xJd7jwc0,829
|
|
58
|
+
basic_memory/mcp/tools/project_info.py,sha256=pyoHpOMhjMIvZFku2iEIpXc2XDtbnNeb-OMrJlYR9LU,1710
|
|
59
|
+
basic_memory/mcp/tools/read_content.py,sha256=PKnvLzNmHfzoIxRKXNaYW5P5q0d1azVwG9juPXPYeQo,8148
|
|
60
|
+
basic_memory/mcp/tools/read_note.py,sha256=pM6FUxMdDxxCNxhnDrkrVqIJouIRPbUqSHsL3BVgiy8,6469
|
|
61
|
+
basic_memory/mcp/tools/recent_activity.py,sha256=S0LgIk9RaeYzIsi2FIHs0KK7R1K-LJy3QaSokGlY9ew,3501
|
|
62
|
+
basic_memory/mcp/tools/search.py,sha256=0PcLCpXe73X72jSudVLVMO8TQwEjnB6F1V9jCtjf2ZE,2999
|
|
63
|
+
basic_memory/mcp/tools/utils.py,sha256=tOWklfSlDcoAJCRBmxkCVwkTY_TDBa5vOGxzU8J5eiQ,13636
|
|
64
|
+
basic_memory/mcp/tools/write_note.py,sha256=CdUdFitmuDQl8z36IqrbSB0hSEdw20k_ZIXnpV_KDSc,4374
|
|
65
|
+
basic_memory/models/__init__.py,sha256=Bf0xXV_ryndogvZDiVM_Wb6iV2fHUxYNGMZNWNcZi0s,307
|
|
66
|
+
basic_memory/models/base.py,sha256=4hAXJ8CE1RnjKhb23lPd-QM7G_FXIdTowMJ9bRixspU,225
|
|
67
|
+
basic_memory/models/knowledge.py,sha256=lbKd8VOOVPqXtIhNMY30bIokoQutFjLpHwLD5At90MY,6644
|
|
68
|
+
basic_memory/models/search.py,sha256=YnF2YnP6NUFf7SSy9xvkY055MlfkBXJuxLoOhCTvB2Q,1244
|
|
69
|
+
basic_memory/repository/__init__.py,sha256=TnscLXARq2iOgQZFvQoT9X1Bn9SB_7s1xw2fOqRs3Jg,252
|
|
70
|
+
basic_memory/repository/entity_repository.py,sha256=VLKlQ97-_HhSqc-st_YToWUNE4pJIcKEOcGDxC25q1k,3575
|
|
71
|
+
basic_memory/repository/observation_repository.py,sha256=BOcy4wARqCXu-thYyt7mPxt2A2C8TW0le3s_X9wrK6I,1701
|
|
72
|
+
basic_memory/repository/project_info_repository.py,sha256=nHWzs0WBQ366WfzIYZgnAfU6tyQ_8slEszWNlDSeIlo,336
|
|
73
|
+
basic_memory/repository/relation_repository.py,sha256=DwpTcn9z_1sZQcyMOUABz1k1VSwo_AU63x2zR7aerTk,2933
|
|
74
|
+
basic_memory/repository/repository.py,sha256=cZFCjp7Q-fKwjEYe3ubG1rgYbPEQXsocAn9LgFNXCG0,12071
|
|
75
|
+
basic_memory/repository/search_repository.py,sha256=82NCjq06JUuUQXQ9k_D-h8BBlO5gl51XF9UdcY8gK8Q,11621
|
|
76
|
+
basic_memory/schemas/__init__.py,sha256=KHzF2lZhYXRsH2g6tV5Oivlk1EHFfrlbKuiRllqnBzs,1570
|
|
77
|
+
basic_memory/schemas/base.py,sha256=dwnaI5fJXsdp81mdH0ZpmJ-WICY-0M7ZPWeW5OUgBG8,5685
|
|
78
|
+
basic_memory/schemas/delete.py,sha256=UAR2JK99WMj3gP-yoGWlHD3eZEkvlTSRf8QoYIE-Wfw,1180
|
|
79
|
+
basic_memory/schemas/memory.py,sha256=qqQm89nZQKtrhquHlRnR6LaSWynPi4MgtcMcqvGH5zg,3136
|
|
80
|
+
basic_memory/schemas/project_info.py,sha256=qsZfafp8bn2oqCizX_CVwJZS4HE79kOmaNiNK9C_9_w,3380
|
|
81
|
+
basic_memory/schemas/request.py,sha256=58r9mPGc4Am9rR_zGzo-yqXcsrl5I6n3M5LjGK5gFFk,1626
|
|
82
|
+
basic_memory/schemas/response.py,sha256=lVYR31DTtSeFRddGWX_wQWnQgyiwX0LEpNJ4f4lKpTM,6440
|
|
83
|
+
basic_memory/schemas/search.py,sha256=mfPHo8lzZ8BMLzmID-0g_0pWHhBIBNIvy4c8KYHFuvQ,3655
|
|
84
|
+
basic_memory/services/__init__.py,sha256=oop6SKmzV4_NAYt9otGnupLGVCCKIVgxEcdRQWwh25I,197
|
|
85
|
+
basic_memory/services/context_service.py,sha256=fhJNHQoTEeIC9ZmZ49CXcNF2aVBghVnmo6LtdSDcAas,9708
|
|
86
|
+
basic_memory/services/entity_service.py,sha256=p4yP-VngdtfCqbvygQ968tGQVOJ1nFzN3XRyXenEcRM,12432
|
|
87
|
+
basic_memory/services/exceptions.py,sha256=VGlCLd4UD2w5NWKqC7QpG4jOM_hA7jKRRM-MqvEVMNk,288
|
|
88
|
+
basic_memory/services/file_service.py,sha256=Mz3_G1DyDcPX9bSR1pRHibqWcpiKtz4E29eoKsjWfYY,9905
|
|
89
|
+
basic_memory/services/link_resolver.py,sha256=yWqqKqJtGU_93xy25y6Us4xRTNijrBLz76Nvm_zFEOI,3326
|
|
90
|
+
basic_memory/services/search_service.py,sha256=t3d5jhABs5bXwtOu7_AvRCpVd8RRd2j6Gg59BAYZ0l8,10625
|
|
91
|
+
basic_memory/services/service.py,sha256=V-d_8gOV07zGIQDpL-Ksqs3ZN9l3qf3HZOK1f_YNTag,336
|
|
92
|
+
basic_memory/sync/__init__.py,sha256=CVHguYH457h2u2xoM8KvOilJC71XJlZ-qUh8lHcjYj4,156
|
|
93
|
+
basic_memory/sync/sync_service.py,sha256=YirSOgk0PyqPJoHXVUzAxhNKdd2pebP8sFeXeAYmGjM,21957
|
|
94
|
+
basic_memory/sync/watch_service.py,sha256=heIImU4d0nrVm5kr-zkHpFN2E3v1Z29LXUR2dLq2TPw,12995
|
|
95
|
+
basic_memory-0.9.0.dist-info/METADATA,sha256=Sz9gDlA_gEgMETHekkK-C2dQqCH73pQHPs4puzncXko,25391
|
|
96
|
+
basic_memory-0.9.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
97
|
+
basic_memory-0.9.0.dist-info/entry_points.txt,sha256=IDQa_VmVTzmvMrpnjhEfM0S3F--XsVGEj3MpdJfuo-Q,59
|
|
98
|
+
basic_memory-0.9.0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
|
99
|
+
basic_memory-0.9.0.dist-info/RECORD,,
|
basic_memory/alembic/README
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Generic single-database configuration.
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
"""Database management commands."""
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
from typing import Optional, List, Annotated
|
|
5
|
-
|
|
6
|
-
import typer
|
|
7
|
-
from rich import print as rprint
|
|
8
|
-
|
|
9
|
-
from basic_memory.cli.app import app
|
|
10
|
-
from basic_memory.mcp.tools import build_context as mcp_build_context
|
|
11
|
-
from basic_memory.mcp.tools import get_entity as mcp_get_entity
|
|
12
|
-
from basic_memory.mcp.tools import read_note as mcp_read_note
|
|
13
|
-
from basic_memory.mcp.tools import recent_activity as mcp_recent_activity
|
|
14
|
-
from basic_memory.mcp.tools import search as mcp_search
|
|
15
|
-
from basic_memory.mcp.tools import write_note as mcp_write_note
|
|
16
|
-
from basic_memory.schemas.base import TimeFrame
|
|
17
|
-
from basic_memory.schemas.memory import MemoryUrl
|
|
18
|
-
from basic_memory.schemas.search import SearchQuery
|
|
19
|
-
|
|
20
|
-
tool_app = typer.Typer()
|
|
21
|
-
app.add_typer(tool_app, name="tools", help="cli versions mcp tools")
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@tool_app.command()
|
|
25
|
-
def write_note(
|
|
26
|
-
title: Annotated[str, typer.Option(help="The title of the note")],
|
|
27
|
-
content: Annotated[str, typer.Option(help="The content of the note")],
|
|
28
|
-
folder: Annotated[str, typer.Option(help="The folder to create the note in")],
|
|
29
|
-
tags: Annotated[
|
|
30
|
-
Optional[List[str]], typer.Option(help="A list of tags to apply to the note")
|
|
31
|
-
] = None,
|
|
32
|
-
):
|
|
33
|
-
try:
|
|
34
|
-
note = asyncio.run(mcp_write_note(title, content, folder, tags))
|
|
35
|
-
rprint(note)
|
|
36
|
-
except Exception as e: # pragma: no cover
|
|
37
|
-
if not isinstance(e, typer.Exit):
|
|
38
|
-
typer.echo(f"Error during write_note: {e}", err=True)
|
|
39
|
-
raise typer.Exit(1)
|
|
40
|
-
raise
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
@tool_app.command()
|
|
44
|
-
def read_note(identifier: str, page: int = 1, page_size: int = 10):
|
|
45
|
-
try:
|
|
46
|
-
note = asyncio.run(mcp_read_note(identifier, page, page_size))
|
|
47
|
-
rprint(note)
|
|
48
|
-
except Exception as e: # pragma: no cover
|
|
49
|
-
if not isinstance(e, typer.Exit):
|
|
50
|
-
typer.echo(f"Error during read_note: {e}", err=True)
|
|
51
|
-
raise typer.Exit(1)
|
|
52
|
-
raise
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
@tool_app.command()
|
|
56
|
-
def build_context(
|
|
57
|
-
url: MemoryUrl,
|
|
58
|
-
depth: Optional[int] = 1,
|
|
59
|
-
timeframe: Optional[TimeFrame] = "7d",
|
|
60
|
-
page: int = 1,
|
|
61
|
-
page_size: int = 10,
|
|
62
|
-
max_related: int = 10,
|
|
63
|
-
):
|
|
64
|
-
try:
|
|
65
|
-
context = asyncio.run(
|
|
66
|
-
mcp_build_context(
|
|
67
|
-
url=url,
|
|
68
|
-
depth=depth,
|
|
69
|
-
timeframe=timeframe,
|
|
70
|
-
page=page,
|
|
71
|
-
page_size=page_size,
|
|
72
|
-
max_related=max_related,
|
|
73
|
-
)
|
|
74
|
-
)
|
|
75
|
-
rprint(context.model_dump())
|
|
76
|
-
except Exception as e: # pragma: no cover
|
|
77
|
-
if not isinstance(e, typer.Exit):
|
|
78
|
-
typer.echo(f"Error during build_context: {e}", err=True)
|
|
79
|
-
raise typer.Exit(1)
|
|
80
|
-
raise
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
@tool_app.command()
|
|
84
|
-
def recent_activity(
|
|
85
|
-
type: Annotated[Optional[List[str]], typer.Option()] = ["entity", "observation", "relation"],
|
|
86
|
-
depth: Optional[int] = 1,
|
|
87
|
-
timeframe: Optional[TimeFrame] = "7d",
|
|
88
|
-
page: int = 1,
|
|
89
|
-
page_size: int = 10,
|
|
90
|
-
max_related: int = 10,
|
|
91
|
-
):
|
|
92
|
-
assert type is not None, "type is required"
|
|
93
|
-
if any(t not in ["entity", "observation", "relation"] for t in type): # pragma: no cover
|
|
94
|
-
print("type must be one of ['entity', 'observation', 'relation']")
|
|
95
|
-
raise typer.Abort()
|
|
96
|
-
|
|
97
|
-
try:
|
|
98
|
-
context = asyncio.run(
|
|
99
|
-
mcp_recent_activity(
|
|
100
|
-
type=type, # pyright: ignore [reportArgumentType]
|
|
101
|
-
depth=depth,
|
|
102
|
-
timeframe=timeframe,
|
|
103
|
-
page=page,
|
|
104
|
-
page_size=page_size,
|
|
105
|
-
max_related=max_related,
|
|
106
|
-
)
|
|
107
|
-
)
|
|
108
|
-
rprint(context.model_dump())
|
|
109
|
-
except Exception as e: # pragma: no cover
|
|
110
|
-
if not isinstance(e, typer.Exit):
|
|
111
|
-
typer.echo(f"Error during build_context: {e}", err=True)
|
|
112
|
-
raise typer.Exit(1)
|
|
113
|
-
raise
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
@tool_app.command()
|
|
117
|
-
def search(
|
|
118
|
-
query: str,
|
|
119
|
-
permalink: Annotated[bool, typer.Option("--permalink", help="Search permalink values")] = False,
|
|
120
|
-
title: Annotated[bool, typer.Option("--title", help="Search title values")] = False,
|
|
121
|
-
after_date: Annotated[
|
|
122
|
-
Optional[str],
|
|
123
|
-
typer.Option("--after_date", help="Search results after date, eg. '2d', '1 week'"),
|
|
124
|
-
] = None,
|
|
125
|
-
page: int = 1,
|
|
126
|
-
page_size: int = 10,
|
|
127
|
-
):
|
|
128
|
-
if permalink and title: # pragma: no cover
|
|
129
|
-
print("Cannot search both permalink and title")
|
|
130
|
-
raise typer.Abort()
|
|
131
|
-
|
|
132
|
-
try:
|
|
133
|
-
search_query = SearchQuery(
|
|
134
|
-
permalink_match=query if permalink else None,
|
|
135
|
-
text=query if query else None,
|
|
136
|
-
title=query if title else None,
|
|
137
|
-
after_date=after_date,
|
|
138
|
-
)
|
|
139
|
-
results = asyncio.run(mcp_search(query=search_query, page=page, page_size=page_size))
|
|
140
|
-
rprint(results.model_dump())
|
|
141
|
-
except Exception as e: # pragma: no cover
|
|
142
|
-
if not isinstance(e, typer.Exit):
|
|
143
|
-
typer.echo(f"Error during search: {e}", err=True)
|
|
144
|
-
raise typer.Exit(1)
|
|
145
|
-
raise
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
@tool_app.command()
|
|
149
|
-
def get_entity(identifier: str):
|
|
150
|
-
try:
|
|
151
|
-
entity = asyncio.run(mcp_get_entity(identifier=identifier))
|
|
152
|
-
rprint(entity.model_dump())
|
|
153
|
-
except Exception as e: # pragma: no cover
|
|
154
|
-
if not isinstance(e, typer.Exit):
|
|
155
|
-
typer.echo(f"Error during get_entity: {e}", err=True)
|
|
156
|
-
raise typer.Exit(1)
|
|
157
|
-
raise
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"""Knowledge graph management tools for Basic Memory MCP server."""
|
|
2
|
-
|
|
3
|
-
import logfire
|
|
4
|
-
|
|
5
|
-
from basic_memory.mcp.server import mcp
|
|
6
|
-
from basic_memory.mcp.tools.utils import call_get, call_post
|
|
7
|
-
from basic_memory.schemas.memory import memory_url_path
|
|
8
|
-
from basic_memory.schemas.request import (
|
|
9
|
-
GetEntitiesRequest,
|
|
10
|
-
)
|
|
11
|
-
from basic_memory.schemas.delete import (
|
|
12
|
-
DeleteEntitiesRequest,
|
|
13
|
-
)
|
|
14
|
-
from basic_memory.schemas.response import EntityListResponse, EntityResponse, DeleteEntitiesResponse
|
|
15
|
-
from basic_memory.mcp.async_client import client
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@mcp.tool(
|
|
19
|
-
description="Get complete information about a specific entity including observations and relations",
|
|
20
|
-
)
|
|
21
|
-
async def get_entity(identifier: str) -> EntityResponse:
|
|
22
|
-
"""Get a specific entity info by its permalink.
|
|
23
|
-
|
|
24
|
-
Args:
|
|
25
|
-
identifier: Path identifier for the entity
|
|
26
|
-
"""
|
|
27
|
-
with logfire.span("Getting entity", permalink=identifier): # pyright: ignore [reportGeneralTypeIssues]
|
|
28
|
-
permalink = memory_url_path(identifier)
|
|
29
|
-
url = f"/knowledge/entities/{permalink}"
|
|
30
|
-
response = await call_get(client, url)
|
|
31
|
-
return EntityResponse.model_validate(response.json())
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@mcp.tool(
|
|
35
|
-
description="Load multiple entities by their permalinks in a single request",
|
|
36
|
-
)
|
|
37
|
-
async def get_entities(request: GetEntitiesRequest) -> EntityListResponse:
|
|
38
|
-
"""Load multiple entities by their permalinks.
|
|
39
|
-
|
|
40
|
-
Args:
|
|
41
|
-
request: OpenNodesRequest containing list of permalinks to load
|
|
42
|
-
|
|
43
|
-
Returns:
|
|
44
|
-
EntityListResponse containing complete details for each requested entity
|
|
45
|
-
"""
|
|
46
|
-
with logfire.span("Getting multiple entities", permalink_count=len(request.permalinks)): # pyright: ignore [reportGeneralTypeIssues]
|
|
47
|
-
url = "/knowledge/entities"
|
|
48
|
-
response = await call_get(
|
|
49
|
-
client,
|
|
50
|
-
url,
|
|
51
|
-
params=[
|
|
52
|
-
("permalink", memory_url_path(identifier)) for identifier in request.permalinks
|
|
53
|
-
],
|
|
54
|
-
)
|
|
55
|
-
return EntityListResponse.model_validate(response.json())
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@mcp.tool(
|
|
59
|
-
description="Permanently delete entities and all related content (observations and relations)",
|
|
60
|
-
)
|
|
61
|
-
async def delete_entities(request: DeleteEntitiesRequest) -> DeleteEntitiesResponse:
|
|
62
|
-
"""Delete entities from the knowledge graph."""
|
|
63
|
-
with logfire.span("Deleting entities", permalink_count=len(request.permalinks)): # pyright: ignore [reportGeneralTypeIssues]
|
|
64
|
-
url = "/knowledge/entities/delete"
|
|
65
|
-
|
|
66
|
-
request.permalinks = [memory_url_path(permlink) for permlink in request.permalinks]
|
|
67
|
-
response = await call_post(client, url, json=request.model_dump())
|
|
68
|
-
return DeleteEntitiesResponse.model_validate(response.json())
|
basic_memory/mcp/tools/memory.py
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
"""Discussion context tools for Basic Memory MCP server."""
|
|
2
|
-
|
|
3
|
-
from typing import Optional, Literal, List
|
|
4
|
-
|
|
5
|
-
from loguru import logger
|
|
6
|
-
import logfire
|
|
7
|
-
|
|
8
|
-
from basic_memory.mcp.async_client import client
|
|
9
|
-
from basic_memory.mcp.server import mcp
|
|
10
|
-
from basic_memory.mcp.tools.utils import call_get
|
|
11
|
-
from basic_memory.schemas.memory import (
|
|
12
|
-
GraphContext,
|
|
13
|
-
MemoryUrl,
|
|
14
|
-
memory_url_path,
|
|
15
|
-
normalize_memory_url,
|
|
16
|
-
)
|
|
17
|
-
from basic_memory.schemas.base import TimeFrame
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@mcp.tool(
|
|
21
|
-
description="""Build context from a memory:// URI to continue conversations naturally.
|
|
22
|
-
|
|
23
|
-
Use this to follow up on previous discussions or explore related topics.
|
|
24
|
-
Timeframes support natural language like:
|
|
25
|
-
- "2 days ago"
|
|
26
|
-
- "last week"
|
|
27
|
-
- "today"
|
|
28
|
-
- "3 months ago"
|
|
29
|
-
Or standard formats like "7d", "24h"
|
|
30
|
-
""",
|
|
31
|
-
)
|
|
32
|
-
async def build_context(
|
|
33
|
-
url: MemoryUrl,
|
|
34
|
-
depth: Optional[int] = 1,
|
|
35
|
-
timeframe: Optional[TimeFrame] = "7d",
|
|
36
|
-
page: int = 1,
|
|
37
|
-
page_size: int = 10,
|
|
38
|
-
max_related: int = 10,
|
|
39
|
-
) -> GraphContext:
|
|
40
|
-
"""Get context needed to continue a discussion.
|
|
41
|
-
|
|
42
|
-
This tool enables natural continuation of discussions by loading relevant context
|
|
43
|
-
from memory:// URIs. It uses pattern matching to find relevant content and builds
|
|
44
|
-
a rich context graph of related information.
|
|
45
|
-
|
|
46
|
-
Args:
|
|
47
|
-
url: memory:// URI pointing to discussion content (e.g. memory://specs/search)
|
|
48
|
-
depth: How many relation hops to traverse (1-3 recommended for performance)
|
|
49
|
-
timeframe: How far back to look. Supports natural language like "2 days ago", "last week"
|
|
50
|
-
page: Page number of results to return (default: 1)
|
|
51
|
-
page_size: Number of results to return per page (default: 10)
|
|
52
|
-
max_related: Maximum number of related results to return (default: 10)
|
|
53
|
-
|
|
54
|
-
Returns:
|
|
55
|
-
GraphContext containing:
|
|
56
|
-
- primary_results: Content matching the memory:// URI
|
|
57
|
-
- related_results: Connected content via relations
|
|
58
|
-
- metadata: Context building details
|
|
59
|
-
|
|
60
|
-
Examples:
|
|
61
|
-
# Continue a specific discussion
|
|
62
|
-
build_context("memory://specs/search")
|
|
63
|
-
|
|
64
|
-
# Get deeper context about a component
|
|
65
|
-
build_context("memory://components/memory-service", depth=2)
|
|
66
|
-
|
|
67
|
-
# Look at recent changes to a specification
|
|
68
|
-
build_context("memory://specs/document-format", timeframe="today")
|
|
69
|
-
|
|
70
|
-
# Research the history of a feature
|
|
71
|
-
build_context("memory://features/knowledge-graph", timeframe="3 months ago")
|
|
72
|
-
"""
|
|
73
|
-
with logfire.span("Building context", url=url, depth=depth, timeframe=timeframe): # pyright: ignore [reportGeneralTypeIssues]
|
|
74
|
-
logger.info(f"Building context from {url}")
|
|
75
|
-
url = normalize_memory_url(url)
|
|
76
|
-
response = await call_get(
|
|
77
|
-
client,
|
|
78
|
-
f"/memory/{memory_url_path(url)}",
|
|
79
|
-
params={
|
|
80
|
-
"depth": depth,
|
|
81
|
-
"timeframe": timeframe,
|
|
82
|
-
"page": page,
|
|
83
|
-
"page_size": page_size,
|
|
84
|
-
"max_related": max_related,
|
|
85
|
-
},
|
|
86
|
-
)
|
|
87
|
-
return GraphContext.model_validate(response.json())
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
@mcp.tool(
|
|
91
|
-
description="""Get recent activity from across the knowledge base.
|
|
92
|
-
|
|
93
|
-
Timeframe supports natural language formats like:
|
|
94
|
-
- "2 days ago"
|
|
95
|
-
- "last week"
|
|
96
|
-
- "yesterday"
|
|
97
|
-
- "today"
|
|
98
|
-
- "3 weeks ago"
|
|
99
|
-
Or standard formats like "7d"
|
|
100
|
-
""",
|
|
101
|
-
)
|
|
102
|
-
async def recent_activity(
|
|
103
|
-
type: List[Literal["entity", "observation", "relation"]] = [],
|
|
104
|
-
depth: Optional[int] = 1,
|
|
105
|
-
timeframe: Optional[TimeFrame] = "7d",
|
|
106
|
-
page: int = 1,
|
|
107
|
-
page_size: int = 10,
|
|
108
|
-
max_related: int = 10,
|
|
109
|
-
) -> GraphContext:
|
|
110
|
-
"""Get recent activity across the knowledge base.
|
|
111
|
-
|
|
112
|
-
Args:
|
|
113
|
-
type: Filter by content type(s). Valid options:
|
|
114
|
-
- ["entity"] for knowledge entities
|
|
115
|
-
- ["relation"] for connections between entities
|
|
116
|
-
- ["observation"] for notes and observations
|
|
117
|
-
Multiple types can be combined: ["entity", "relation"]
|
|
118
|
-
depth: How many relation hops to traverse (1-3 recommended)
|
|
119
|
-
timeframe: Time window to search. Supports natural language:
|
|
120
|
-
- Relative: "2 days ago", "last week", "yesterday"
|
|
121
|
-
- Points in time: "2024-01-01", "January 1st"
|
|
122
|
-
- Standard format: "7d", "24h"
|
|
123
|
-
page: Page number of results to return (default: 1)
|
|
124
|
-
page_size: Number of results to return per page (default: 10)
|
|
125
|
-
max_related: Maximum number of related results to return (default: 10)
|
|
126
|
-
|
|
127
|
-
Returns:
|
|
128
|
-
GraphContext containing:
|
|
129
|
-
- primary_results: Latest activities matching the filters
|
|
130
|
-
- related_results: Connected content via relations
|
|
131
|
-
- metadata: Query details and statistics
|
|
132
|
-
|
|
133
|
-
Examples:
|
|
134
|
-
# Get all entities for the last 10 days (default)
|
|
135
|
-
recent_activity()
|
|
136
|
-
|
|
137
|
-
# Get all entities from yesterday
|
|
138
|
-
recent_activity(type=["entity"], timeframe="yesterday")
|
|
139
|
-
|
|
140
|
-
# Get recent relations and observations
|
|
141
|
-
recent_activity(type=["relation", "observation"], timeframe="today")
|
|
142
|
-
|
|
143
|
-
# Look back further with more context
|
|
144
|
-
recent_activity(type=["entity"], depth=2, timeframe="2 weeks ago")
|
|
145
|
-
|
|
146
|
-
Notes:
|
|
147
|
-
- Higher depth values (>3) may impact performance with large result sets
|
|
148
|
-
- For focused queries, consider using build_context with a specific URI
|
|
149
|
-
- Max timeframe is 1 year in the past
|
|
150
|
-
"""
|
|
151
|
-
with logfire.span("Getting recent activity", type=type, depth=depth, timeframe=timeframe): # pyright: ignore [reportGeneralTypeIssues]
|
|
152
|
-
logger.info(
|
|
153
|
-
f"Getting recent activity from {type}, depth={depth}, timeframe={timeframe}, page={page}, page_size={page_size}, max_related={max_related}"
|
|
154
|
-
)
|
|
155
|
-
params = {
|
|
156
|
-
"depth": depth,
|
|
157
|
-
"timeframe": timeframe,
|
|
158
|
-
"page": page,
|
|
159
|
-
"page_size": page_size,
|
|
160
|
-
"max_related": max_related,
|
|
161
|
-
}
|
|
162
|
-
if type:
|
|
163
|
-
params["type"] = type
|
|
164
|
-
|
|
165
|
-
response = await call_get(
|
|
166
|
-
client,
|
|
167
|
-
"/memory/recent",
|
|
168
|
-
params=params,
|
|
169
|
-
)
|
|
170
|
-
return GraphContext.model_validate(response.json())
|