MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / handle_list_projects

Function handle_list_projects

src/mcp/mcp.c:2581–2708  ·  view source on GitHub ↗

list_projects: scan cache directory for .db files. * Each project is a single .db file — no central registry needed. */

Source from the content-addressed store, hash-verified

2579/* list_projects: scan cache directory for .db files.
2580 * Each project is a single .db file — no central registry needed. */
2581static char *handle_list_projects(cbm_mcp_server_t *srv, const char *args) {
2582 (void)srv;
2583 int offset = cbm_mcp_get_int_arg(args, "offset", 0);
2584 int limit = cbm_mcp_get_int_arg(args, "limit", 50);
2585 bool include_details = cbm_mcp_get_bool_arg(args, "include_details");
2586 yyjson_doc *args_doc = args ? yyjson_read(args, strlen(args), 0) : NULL;
2587 yyjson_val *args_root = args_doc ? yyjson_doc_get_root(args_doc) : NULL;
2588 yyjson_val *metadata_value =
2589 args_root && yyjson_is_obj(args_root) ? yyjson_obj_get(args_root, "metadata_only") : NULL;
2590 if (metadata_value && yyjson_is_true(metadata_value)) {
2591 include_details = false;
2592 }
2593 if (args_doc) {
2594 yyjson_doc_free(args_doc);
2595 }
2596 if (offset < 0) {
2597 offset = 0;
2598 }
2599 if (limit < 1) {
2600 limit = 1;
2601 } else if (limit > 100) {
2602 limit = 100;
2603 }
2604
2605 char dir_path[CBM_SZ_1K];
2606 cache_dir(dir_path, sizeof(dir_path));
2607
2608 cbm_dir_t *d = cbm_opendir(dir_path);
2609
2610 yyjson_mut_doc *doc = yyjson_mut_doc_new(NULL);
2611 yyjson_mut_val *root = yyjson_mut_obj(doc);
2612 yyjson_mut_doc_set_root(doc, root);
2613 yyjson_mut_val *arr = yyjson_mut_arr(doc);
2614
2615 if (!d) {
2616 char msg[CBM_SZ_1K];
2617 snprintf(msg, sizeof(msg),
2618 "{\"error\":\"cannot read cache directory: %s\",\"hint\":"
2619 "\"Check directory permissions or run index_repository first.\"}",
2620 dir_path);
2621 yyjson_mut_doc_free(doc);
2622 return cbm_mcp_text_result(msg, true);
2623 }
2624
2625 char **db_names = NULL;
2626 size_t db_count = 0;
2627 size_t db_cap = 0;
2628 bool name_collection_failed = false;
2629 cbm_dirent_t *entry;
2630 while ((entry = cbm_readdir(d)) != NULL) {
2631 const char *name = entry->name;
2632 size_t len = strlen(name);
2633 if (!is_project_db_file(name, len)) {
2634 continue;
2635 }
2636 if (db_count == db_cap) {
2637 size_t next_cap = db_cap ? db_cap * 2 : 64;
2638 char **grown = realloc(db_names, next_cap * sizeof(*db_names));

Callers 1

dispatch_toolFunction · 0.85

Calls 12

cbm_mcp_get_int_argFunction · 0.85
cbm_mcp_get_bool_argFunction · 0.85
cache_dirFunction · 0.85
cbm_opendirFunction · 0.85
cbm_mcp_text_resultFunction · 0.85
cbm_readdirFunction · 0.85
is_project_db_fileFunction · 0.85
cbm_closedirFunction · 0.85
cbm_file_sizeFunction · 0.85
build_project_json_entryFunction · 0.85
yy_doc_to_strFunction · 0.85
heap_strdupFunction · 0.70

Tested by

no test coverage detected