@nex-ai/nex 0.1.34 → 0.1.36

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.
Files changed (73) hide show
  1. package/README.md +18 -4
  2. package/dist/index.js +6 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/lib/workspace-registry.d.ts +47 -0
  5. package/dist/lib/workspace-registry.js +240 -0
  6. package/dist/lib/workspace-registry.js.map +1 -0
  7. package/dist/mcp/channel.d.ts +28 -0
  8. package/dist/mcp/channel.js +135 -0
  9. package/dist/mcp/channel.js.map +1 -0
  10. package/dist/mcp/client.d.ts +20 -0
  11. package/dist/mcp/client.js +130 -0
  12. package/dist/mcp/client.js.map +1 -0
  13. package/dist/mcp/config.d.ts +14 -0
  14. package/dist/mcp/config.js +33 -0
  15. package/dist/mcp/config.js.map +1 -0
  16. package/dist/mcp/context-files.d.ts +9 -0
  17. package/dist/mcp/context-files.js +90 -0
  18. package/dist/mcp/context-files.js.map +1 -0
  19. package/dist/mcp/file-manifest.d.ts +27 -0
  20. package/dist/mcp/file-manifest.js +64 -0
  21. package/dist/mcp/file-manifest.js.map +1 -0
  22. package/dist/mcp/file-scanner.d.ts +17 -0
  23. package/dist/mcp/file-scanner.js +77 -0
  24. package/dist/mcp/file-scanner.js.map +1 -0
  25. package/dist/mcp/index.d.ts +2 -0
  26. package/dist/mcp/index.js +51 -0
  27. package/dist/mcp/index.js.map +1 -0
  28. package/dist/mcp/rate-limiter.d.ts +14 -0
  29. package/dist/mcp/rate-limiter.js +60 -0
  30. package/dist/mcp/rate-limiter.js.map +1 -0
  31. package/dist/mcp/server.d.ts +6 -0
  32. package/dist/mcp/server.js +42 -0
  33. package/dist/mcp/server.js.map +1 -0
  34. package/dist/mcp/session-store.d.ts +16 -0
  35. package/dist/mcp/session-store.js +70 -0
  36. package/dist/mcp/session-store.js.map +1 -0
  37. package/dist/mcp/tools/context.d.ts +3 -0
  38. package/dist/mcp/tools/context.js +65 -0
  39. package/dist/mcp/tools/context.js.map +1 -0
  40. package/dist/mcp/tools/insights.d.ts +3 -0
  41. package/dist/mcp/tools/insights.js +24 -0
  42. package/dist/mcp/tools/insights.js.map +1 -0
  43. package/dist/mcp/tools/integrations.d.ts +3 -0
  44. package/dist/mcp/tools/integrations.js +27 -0
  45. package/dist/mcp/tools/integrations.js.map +1 -0
  46. package/dist/mcp/tools/lists.d.ts +3 -0
  47. package/dist/mcp/tools/lists.js +101 -0
  48. package/dist/mcp/tools/lists.js.map +1 -0
  49. package/dist/mcp/tools/notes.d.ts +3 -0
  50. package/dist/mcp/tools/notes.js +52 -0
  51. package/dist/mcp/tools/notes.js.map +1 -0
  52. package/dist/mcp/tools/records.d.ts +3 -0
  53. package/dist/mcp/tools/records.js +74 -0
  54. package/dist/mcp/tools/records.js.map +1 -0
  55. package/dist/mcp/tools/register.d.ts +3 -0
  56. package/dist/mcp/tools/register.js +30 -0
  57. package/dist/mcp/tools/register.js.map +1 -0
  58. package/dist/mcp/tools/relationships.d.ts +3 -0
  59. package/dist/mcp/tools/relationships.js +47 -0
  60. package/dist/mcp/tools/relationships.js.map +1 -0
  61. package/dist/mcp/tools/scan.d.ts +3 -0
  62. package/dist/mcp/tools/scan.js +37 -0
  63. package/dist/mcp/tools/scan.js.map +1 -0
  64. package/dist/mcp/tools/schema.d.ts +3 -0
  65. package/dist/mcp/tools/schema.js +108 -0
  66. package/dist/mcp/tools/schema.js.map +1 -0
  67. package/dist/mcp/tools/search.d.ts +3 -0
  68. package/dist/mcp/tools/search.js +8 -0
  69. package/dist/mcp/tools/search.js.map +1 -0
  70. package/dist/mcp/tools/tasks.d.ts +3 -0
  71. package/dist/mcp/tools/tasks.js +88 -0
  72. package/dist/mcp/tools/tasks.js.map +1 -0
  73. package/package.json +6 -3
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+ import { persistRegistration, CONFIG_PATH } from "../config.js";
3
+ export function registerRegistrationTools(server, client) {
4
+ server.tool("register", `Register for a Nex API key. Call this first if no NEX_API_KEY is configured. Requires the user's email. After successful registration, the API key is saved to ${CONFIG_PATH} and all other tools become available immediately. Returns the API key, workspace info, and plan details.`, {
5
+ email: z.string().email().describe("User's email address (required for registration)"),
6
+ name: z.string().optional().describe("User's full name"),
7
+ company_name: z.string().optional().describe("Company or organization name"),
8
+ }, { readOnlyHint: false }, async ({ email, name, company_name }) => {
9
+ if (client.isAuthenticated) {
10
+ return {
11
+ content: [{
12
+ type: "text",
13
+ text: JSON.stringify({ message: "Already registered. API key is configured and active. You can use all other tools." }),
14
+ }],
15
+ };
16
+ }
17
+ const result = await client.register(email, name, company_name);
18
+ persistRegistration(result);
19
+ return {
20
+ content: [{
21
+ type: "text",
22
+ text: JSON.stringify({
23
+ ...result,
24
+ _config_saved_to: CONFIG_PATH,
25
+ }, null, 2),
26
+ }],
27
+ };
28
+ });
29
+ }
30
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/mcp/tools/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,UAAU,yBAAyB,CAAC,MAAiB,EAAE,MAAoB;IAC/E,MAAM,CAAC,IAAI,CACT,UAAU,EACV,kKAAkK,WAAW,2GAA2G,EACxR;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC;QACtF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;QACxD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8BAA8B,CAAC;KAC7E,EACD,EAAE,YAAY,EAAE,KAAK,EAAE,EACvB,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE;QACtC,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YAC3B,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,oFAAoF,EAAE,CAAC;qBACxH,CAAC;aACH,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;QAChE,mBAAmB,CAAC,MAAiC,CAAC,CAAC;QACvD,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,GAAI,MAAkC;wBACtC,gBAAgB,EAAE,WAAW;qBAC9B,EAAE,IAAI,EAAE,CAAC,CAAC;iBACZ,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { NexApiClient } from "../client.js";
3
+ export declare function registerRelationshipTools(server: McpServer, client: NexApiClient): void;
@@ -0,0 +1,47 @@
1
+ import { z } from "zod";
2
+ export function registerRelationshipTools(server, client) {
3
+ server.tool("create_relationship_definition", "Define a new relationship type between two object types (e.g. person 'works at' company).", {
4
+ type: z.enum(["one_to_one", "one_to_many", "many_to_many"]).describe("Relationship cardinality"),
5
+ entity_definition_1_id: z.string().describe("First object definition ID"),
6
+ entity_definition_2_id: z.string().describe("Second object definition ID"),
7
+ entity_1_to_2_predicate: z.string().optional().describe("Label for 1→2 direction (e.g. 'works at')"),
8
+ entity_2_to_1_predicate: z.string().optional().describe("Label for 2→1 direction (e.g. 'employs')"),
9
+ }, { readOnlyHint: false }, async ({ type, entity_definition_1_id, entity_definition_2_id, entity_1_to_2_predicate, entity_2_to_1_predicate }) => {
10
+ const body = { type, entity_definition_1_id, entity_definition_2_id };
11
+ if (entity_1_to_2_predicate !== undefined)
12
+ body.entity_1_to_2_predicate = entity_1_to_2_predicate;
13
+ if (entity_2_to_1_predicate !== undefined)
14
+ body.entity_2_to_1_predicate = entity_2_to_1_predicate;
15
+ const result = await client.post("/v1/relationships", body);
16
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
17
+ });
18
+ server.tool("list_relationship_definitions", "List all relationship type definitions in the workspace.", {}, { readOnlyHint: true }, async () => {
19
+ const result = await client.get("/v1/relationships");
20
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
21
+ });
22
+ server.tool("delete_relationship_definition", "Delete a relationship type definition. This removes all instances of this relationship. Cannot be undone.", { id: z.string().describe("Relationship definition ID to delete") }, { readOnlyHint: false, destructiveHint: true }, async ({ id }) => {
23
+ const result = await client.delete(`/v1/relationships/${encodeURIComponent(id)}`);
24
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
25
+ });
26
+ server.tool("create_relationship", "Link two records using an existing relationship definition.", {
27
+ record_id: z.string().describe("Record ID to create the relationship from (used in the URL path)"),
28
+ definition_id: z.string().describe("Relationship definition ID"),
29
+ entity_1_id: z.string().describe("First record ID"),
30
+ entity_2_id: z.string().describe("Second record ID"),
31
+ }, { readOnlyHint: false }, async ({ record_id, definition_id, entity_1_id, entity_2_id }) => {
32
+ const result = await client.post(`/v1/records/${encodeURIComponent(record_id)}/relationships`, {
33
+ definition_id,
34
+ entity_1_id,
35
+ entity_2_id,
36
+ });
37
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
38
+ });
39
+ server.tool("delete_relationship", "Remove a relationship between two records. Cannot be undone.", {
40
+ record_id: z.string().describe("Record ID"),
41
+ relationship_id: z.string().describe("Relationship instance ID to delete"),
42
+ }, { readOnlyHint: false, destructiveHint: true }, async ({ record_id, relationship_id }) => {
43
+ const result = await client.delete(`/v1/records/${encodeURIComponent(record_id)}/relationships/${encodeURIComponent(relationship_id)}`);
44
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
45
+ });
46
+ }
47
+ //# sourceMappingURL=relationships.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationships.js","sourceRoot":"","sources":["../../../src/mcp/tools/relationships.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { NexApiClient } from "../client.js";
3
+ export declare function registerScanTools(server: McpServer, client: NexApiClient): void;
@@ -0,0 +1,37 @@
1
+ import { z } from "zod";
2
+ import { RateLimiter } from "../rate-limiter.js";
3
+ import { scanAndIngest } from "../file-scanner.js";
4
+ import { ingestContextFiles } from "../context-files.js";
5
+ import { readManifest, markScanned, writeManifest } from "../file-manifest.js";
6
+ const rateLimiter = new RateLimiter();
7
+ export function registerScanTools(server, client) {
8
+ server.tool("scan_files", "Scan a directory for text files and ingest changed ones into the Nex knowledge base. Uses manifest-based change detection — unchanged files are skipped automatically.", {
9
+ directory: z.string().optional().describe("Directory to scan (default: current working directory)"),
10
+ max_files: z.number().optional().describe("Maximum files to ingest per scan (default: 5)"),
11
+ max_depth: z.number().optional().describe("Maximum directory depth (default: 2)"),
12
+ }, { readOnlyHint: false }, async ({ directory, max_files, max_depth }) => {
13
+ const scanConfig = {
14
+ enabled: true,
15
+ extensions: [".md", ".txt", ".csv", ".json", ".yaml", ".yml"],
16
+ maxFileSize: 100_000,
17
+ maxFilesPerScan: max_files ?? 5,
18
+ scanDepth: max_depth ?? 2,
19
+ ignoreDirs: ["node_modules", ".git", "dist", "build", ".next", "__pycache__", "vendor", ".venv", ".claude", "coverage", ".turbo", ".cache"],
20
+ };
21
+ const cwd = directory || process.cwd();
22
+ const result = await scanAndIngest(client, rateLimiter, cwd, scanConfig);
23
+ // Mark scan time so session start can skip if fresh
24
+ const manifest = readManifest();
25
+ markScanned(manifest);
26
+ writeManifest(manifest);
27
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
28
+ });
29
+ server.tool("ingest_context_files", "Ingest CLAUDE.md and memory files from the current project into Nex. Uses manifest-based change detection.", {
30
+ directory: z.string().optional().describe("Project directory (default: current working directory)"),
31
+ }, { readOnlyHint: false }, async ({ directory }) => {
32
+ const cwd = directory || process.cwd();
33
+ const result = await ingestContextFiles(client, rateLimiter, cwd);
34
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
35
+ });
36
+ }
37
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/mcp/tools/scan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE/E,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;AAEtC,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,MAAoB;IACvE,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,wKAAwK,EACxK;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;QACnG,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;QAC1F,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;KAClF,EACD,EAAE,YAAY,EAAE,KAAK,EAAE,EACvB,KAAK,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE;QAC5C,MAAM,UAAU,GAAG;YACjB,OAAO,EAAE,IAAI;YACb,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC;YAC7D,WAAW,EAAE,OAAO;YACpB,eAAe,EAAE,SAAS,IAAI,CAAC;YAC/B,SAAS,EAAE,SAAS,IAAI,CAAC;YACzB,UAAU,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC;SAC5I,CAAC;QACF,MAAM,GAAG,GAAG,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;QAEzE,oDAAoD;QACpD,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;QAChC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACtB,aAAa,CAAC,QAAQ,CAAC,CAAC;QAExB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAChF,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,4GAA4G,EAC5G;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wDAAwD,CAAC;KACpG,EACD,EAAE,YAAY,EAAE,KAAK,EAAE,EACvB,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QACtB,MAAM,GAAG,GAAG,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;QAClE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAChF,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { NexApiClient } from "../client.js";
3
+ export declare function registerSchemaTools(server: McpServer, client: NexApiClient): void;
@@ -0,0 +1,108 @@
1
+ import { z } from "zod";
2
+ export function registerSchemaTools(server, client) {
3
+ server.tool("create_object", "Create a new custom object type definition (e.g. 'Project', 'Deal'). Defines the schema for a new entity type in your workspace.", {
4
+ name: z.string().describe("Display name for the object type"),
5
+ slug: z.string().describe("URL-safe identifier (lowercase, hyphens)"),
6
+ name_plural: z.string().optional().describe("Plural display name"),
7
+ description: z.string().optional().describe("Description of the object type"),
8
+ type: z.enum(["person", "company", "custom", "deal"]).optional().describe("Object category (default: custom)"),
9
+ }, { readOnlyHint: false }, async ({ name, slug, name_plural, description, type }) => {
10
+ const body = { name, slug };
11
+ if (name_plural !== undefined)
12
+ body.name_plural = name_plural;
13
+ if (description !== undefined)
14
+ body.description = description;
15
+ if (type !== undefined)
16
+ body.type = type;
17
+ const result = await client.post("/v1/objects", body);
18
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
19
+ });
20
+ server.tool("get_object", "Get a single object type definition with its attributes. Use this to discover available fields before creating or querying records.", { slug: z.string().describe("Object type slug (e.g. 'person', 'company', 'deal')") }, { readOnlyHint: true }, async ({ slug }) => {
21
+ const result = await client.get(`/v1/objects/${encodeURIComponent(slug)}`);
22
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
23
+ });
24
+ server.tool("list_objects", "List all object type definitions in the workspace. Call this first to discover available object types and their schemas before creating or querying records.", {
25
+ include_attributes: z.boolean().optional().describe("Include attribute definitions in the response"),
26
+ }, { readOnlyHint: true }, async ({ include_attributes }) => {
27
+ const params = new URLSearchParams();
28
+ if (include_attributes)
29
+ params.set("include_attributes", "true");
30
+ const qs = params.toString();
31
+ const path = `/v1/objects${qs ? `?${qs}` : ""}`;
32
+ const result = await client.get(path);
33
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
34
+ });
35
+ server.tool("update_object", "Update an existing object type definition (name, description, plural name).", {
36
+ slug: z.string().describe("Object type slug to update"),
37
+ name: z.string().optional().describe("New display name"),
38
+ name_plural: z.string().optional().describe("New plural display name"),
39
+ description: z.string().optional().describe("New description"),
40
+ }, { readOnlyHint: false }, async ({ slug, name, name_plural, description }) => {
41
+ const body = {};
42
+ if (name !== undefined)
43
+ body.name = name;
44
+ if (name_plural !== undefined)
45
+ body.name_plural = name_plural;
46
+ if (description !== undefined)
47
+ body.description = description;
48
+ const result = await client.patch(`/v1/objects/${encodeURIComponent(slug)}`, body);
49
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
50
+ });
51
+ server.tool("delete_object", "Delete an object type definition and ALL its records. This is destructive and cannot be undone.", { slug: z.string().describe("Object type slug to delete") }, { readOnlyHint: false, destructiveHint: true }, async ({ slug }) => {
52
+ const result = await client.delete(`/v1/objects/${encodeURIComponent(slug)}`);
53
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
54
+ });
55
+ server.tool("create_attribute", "Add a new attribute (field) to an object type. Supports types: text, number, email, phone, url, date, boolean, currency, location, select, social_profile, domain, full_name.", {
56
+ object_slug: z.string().describe("Object type slug to add the attribute to"),
57
+ name: z.string().describe("Display name for the attribute"),
58
+ slug: z.string().describe("URL-safe identifier for the attribute"),
59
+ type: z.enum(["text", "number", "email", "phone", "url", "date", "boolean", "currency", "location", "select", "social_profile", "domain", "full_name"]).describe("Attribute data type"),
60
+ description: z.string().optional().describe("Description of the attribute"),
61
+ options: z.object({
62
+ is_required: z.boolean().optional(),
63
+ is_unique: z.boolean().optional(),
64
+ is_multi_value: z.boolean().optional(),
65
+ use_raw_format: z.boolean().optional(),
66
+ is_whole_number: z.boolean().optional(),
67
+ select_options: z.array(z.object({ name: z.string() })).optional(),
68
+ }).optional().describe("Attribute options"),
69
+ }, { readOnlyHint: false }, async ({ object_slug, name, slug, type, description, options }) => {
70
+ const body = { name, slug, type };
71
+ if (description !== undefined)
72
+ body.description = description;
73
+ if (options)
74
+ body.options = options;
75
+ const result = await client.post(`/v1/objects/${encodeURIComponent(object_slug)}/attributes`, body);
76
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
77
+ });
78
+ server.tool("update_attribute", "Update an existing attribute definition on an object type.", {
79
+ object_slug: z.string().describe("Object type slug"),
80
+ attribute_id: z.string().describe("Attribute ID to update"),
81
+ name: z.string().optional().describe("New display name"),
82
+ description: z.string().optional().describe("New description"),
83
+ options: z.object({
84
+ is_required: z.boolean().optional(),
85
+ select_options: z.array(z.object({ name: z.string() })).optional(),
86
+ use_raw_format: z.boolean().optional(),
87
+ is_whole_number: z.boolean().optional(),
88
+ }).optional().describe("Updated options"),
89
+ }, { readOnlyHint: false }, async ({ object_slug, attribute_id, name, description, options }) => {
90
+ const body = {};
91
+ if (name !== undefined)
92
+ body.name = name;
93
+ if (description !== undefined)
94
+ body.description = description;
95
+ if (options)
96
+ body.options = options;
97
+ const result = await client.patch(`/v1/objects/${encodeURIComponent(object_slug)}/attributes/${encodeURIComponent(attribute_id)}`, body);
98
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
99
+ });
100
+ server.tool("delete_attribute", "Delete an attribute from an object type. This removes the field and its data from all records. Cannot be undone.", {
101
+ object_slug: z.string().describe("Object type slug"),
102
+ attribute_id: z.string().describe("Attribute ID to delete"),
103
+ }, { readOnlyHint: false, destructiveHint: true }, async ({ object_slug, attribute_id }) => {
104
+ const result = await client.delete(`/v1/objects/${encodeURIComponent(object_slug)}/attributes/${encodeURIComponent(attribute_id)}`);
105
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
106
+ });
107
+ }
108
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/mcp/tools/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { NexApiClient } from "../client.js";
3
+ export declare function registerSearchTools(server: McpServer, client: NexApiClient): void;
@@ -0,0 +1,8 @@
1
+ import { z } from "zod";
2
+ export function registerSearchTools(server, client) {
3
+ server.tool("search_records", "Search records by name across all object types (person, company, deal, etc.). Returns matches grouped by object type with relevance scores.", { query: z.string().min(1).max(500).describe("Search query (1-500 characters)") }, { readOnlyHint: true }, async ({ query }) => {
4
+ const result = await client.post("/v1/search", { query });
5
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
6
+ });
7
+ }
8
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/mcp/tools/search.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,MAAoB;IACzE,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,6IAA6I,EAC7I,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC,EAAE,EACjF,EAAE,YAAY,EAAE,IAAI,EAAE,EACtB,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAClB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAChF,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { NexApiClient } from "../client.js";
3
+ export declare function registerTaskTools(server: McpServer, client: NexApiClient): void;
@@ -0,0 +1,88 @@
1
+ import { z } from "zod";
2
+ export function registerTaskTools(server, client) {
3
+ server.tool("create_task", "Create a new task, optionally linked to records and assigned to users.", {
4
+ title: z.string().min(1).describe("Task title"),
5
+ description: z.string().optional().describe("Task description"),
6
+ priority: z.enum(["low", "medium", "high", "urgent"]).optional().describe("Task priority (default: unspecified)"),
7
+ due_date: z.string().optional().describe("Due date in RFC3339 format"),
8
+ entity_ids: z.array(z.string()).optional().describe("Associated record IDs"),
9
+ assignee_ids: z.array(z.string()).optional().describe("Assigned user IDs"),
10
+ }, { readOnlyHint: false }, async ({ title, description, priority, due_date, entity_ids, assignee_ids }) => {
11
+ const body = { title };
12
+ if (description !== undefined)
13
+ body.description = description;
14
+ if (priority !== undefined)
15
+ body.priority = priority;
16
+ if (due_date !== undefined)
17
+ body.due_date = due_date;
18
+ if (entity_ids)
19
+ body.entity_ids = entity_ids;
20
+ if (assignee_ids)
21
+ body.assignee_ids = assignee_ids;
22
+ const result = await client.post("/v1/tasks", body);
23
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
24
+ });
25
+ server.tool("list_tasks", "List tasks with optional filtering by record, assignee, completion status, or search query.", {
26
+ entity_id: z.string().optional().describe("Filter by associated record ID"),
27
+ assignee_id: z.string().optional().describe("Filter by assignee user ID"),
28
+ search: z.string().optional().describe("Search task titles"),
29
+ is_completed: z.boolean().optional().describe("Filter by completion status"),
30
+ limit: z.number().optional().describe("Max results (1-500, default: 100)"),
31
+ offset: z.number().optional().describe("Pagination offset"),
32
+ }, { readOnlyHint: true }, async ({ entity_id, assignee_id, search, is_completed, limit, offset }) => {
33
+ const params = new URLSearchParams();
34
+ if (entity_id)
35
+ params.set("entity_id", entity_id);
36
+ if (assignee_id)
37
+ params.set("assignee_id", assignee_id);
38
+ if (search)
39
+ params.set("search", search);
40
+ if (is_completed !== undefined)
41
+ params.set("is_completed", String(is_completed));
42
+ if (limit !== undefined)
43
+ params.set("limit", String(limit));
44
+ if (offset !== undefined)
45
+ params.set("offset", String(offset));
46
+ const qs = params.toString();
47
+ const path = `/v1/tasks${qs ? `?${qs}` : ""}`;
48
+ const result = await client.get(path);
49
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
50
+ });
51
+ server.tool("get_task", "Get a single task by ID.", { task_id: z.string().describe("Task ID") }, { readOnlyHint: true }, async ({ task_id }) => {
52
+ const result = await client.get(`/v1/tasks/${encodeURIComponent(task_id)}`);
53
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
54
+ });
55
+ server.tool("update_task", "Update a task's fields. All fields are optional — only provided fields are changed.", {
56
+ task_id: z.string().describe("Task ID to update"),
57
+ title: z.string().optional().describe("New title"),
58
+ description: z.string().optional().describe("New description (empty string clears it)"),
59
+ priority: z.string().optional().describe("New priority (empty string clears it)"),
60
+ due_date: z.string().optional().describe("New due date in RFC3339 format"),
61
+ is_completed: z.boolean().optional().describe("Mark complete/incomplete"),
62
+ entity_ids: z.array(z.string()).optional().describe("Replace associated record IDs"),
63
+ assignee_ids: z.array(z.string()).optional().describe("Replace assignee user IDs"),
64
+ }, { readOnlyHint: false }, async ({ task_id, title, description, priority, due_date, is_completed, entity_ids, assignee_ids }) => {
65
+ const body = {};
66
+ if (title !== undefined)
67
+ body.title = title;
68
+ if (description !== undefined)
69
+ body.description = description;
70
+ if (priority !== undefined)
71
+ body.priority = priority;
72
+ if (due_date !== undefined)
73
+ body.due_date = due_date;
74
+ if (is_completed !== undefined)
75
+ body.is_completed = is_completed;
76
+ if (entity_ids !== undefined)
77
+ body.entity_ids = entity_ids;
78
+ if (assignee_ids !== undefined)
79
+ body.assignee_ids = assignee_ids;
80
+ const result = await client.patch(`/v1/tasks/${encodeURIComponent(task_id)}`, body);
81
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
82
+ });
83
+ server.tool("delete_task", "Archive a task (soft delete). Cannot be undone via API.", { task_id: z.string().describe("Task ID to delete") }, { readOnlyHint: false, destructiveHint: true }, async ({ task_id }) => {
84
+ const result = await client.delete(`/v1/tasks/${encodeURIComponent(task_id)}`);
85
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
86
+ });
87
+ }
88
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/mcp/tools/tasks.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@nex-ai/nex",
3
- "version": "0.1.34",
3
+ "version": "0.1.36",
4
4
  "description": "Nex CLI provides organizational context & memory to AI agents",
5
5
  "type": "module",
6
6
  "bin": {
7
- "nex": "dist/index.js"
7
+ "nex": "dist/index.js",
8
+ "nex-mcp": "dist/mcp/index.js"
8
9
  },
9
10
  "files": [
10
11
  "dist",
@@ -43,8 +44,10 @@
43
44
  "license": "MIT",
44
45
  "dependencies": {
45
46
  "@inkjs/ui": "^2.0.0",
47
+ "@modelcontextprotocol/sdk": "^1.12.0",
46
48
  "commander": "^14.0.3",
47
49
  "ink": "^5.2.1",
48
- "react": "^18.3.1"
50
+ "react": "^18.3.1",
51
+ "zod": "^3.25.0"
49
52
  }
50
53
  }