automd-mcp 0.2.1 → 0.2.2

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 (2) hide show
  1. package/dist/index.js +43 -11
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -40506,6 +40506,16 @@ var api = {
40506
40506
  body: JSON.stringify(data)
40507
40507
  }),
40508
40508
  deleteProject: (id) => request(`/api/projects/${id}`, { method: "DELETE" }),
40509
+ // Tags
40510
+ getTags: (projectId) => {
40511
+ const query = new URLSearchParams();
40512
+ if (projectId) query.set("projectId", projectId);
40513
+ return request(`/api/tags?${query.toString()}`);
40514
+ },
40515
+ updateInstanceTags: (tags) => request("/api/tags", {
40516
+ method: "PUT",
40517
+ body: JSON.stringify({ tags })
40518
+ }),
40509
40519
  // Health
40510
40520
  health: () => request("/api/health")
40511
40521
  };
@@ -40605,7 +40615,7 @@ function registerTools(server2) {
40605
40615
  });
40606
40616
  server2.registerTool("add_task", {
40607
40617
  title: "Add Task",
40608
- description: "Add a new task (## H2 heading) to a column. Content supports inline metadata: @user #label priority:high|medium|low due:YYYY-MM-DD est:4h knowledge:true. Do not include built-by: manually \u2014 use the agentName parameter.",
40618
+ description: "Add a new task (## H2 heading) to a column. Content supports inline metadata: @user #label priority:high|medium|low due:YYYY-MM-DD est:4h knowledge:true. Do not include built-by: manually \u2014 use the agentName parameter. Call list_tags to discover existing labels before inventing new ones.",
40609
40619
  inputSchema: {
40610
40620
  itemId: external_exports.string().describe("The item ID"),
40611
40621
  columnId: external_exports.string().describe("The column ID (found in get_item response columns[].id)"),
@@ -40750,7 +40760,7 @@ function registerTools(server2) {
40750
40760
  });
40751
40761
  server2.registerTool("update_task_metadata", {
40752
40762
  title: "Update Task Metadata",
40753
- description: "Update a task's metadata (priority, assignees, labels, due date, estimate) without rewriting its content",
40763
+ description: "Update a task's metadata (priority, assignees, labels, due date, estimate) without rewriting its content. Call list_tags to discover existing labels before adding new ones.",
40754
40764
  inputSchema: {
40755
40765
  itemId: external_exports.string().describe("The item ID"),
40756
40766
  taskId: external_exports.string().describe("The task ID"),
@@ -40871,7 +40881,7 @@ function registerTools(server2) {
40871
40881
  });
40872
40882
  server2.registerTool("search_tasks", {
40873
40883
  title: "Search Tasks",
40874
- description: "Search for tasks across all items by text, assignee, label, or status",
40884
+ description: "Search for tasks across all items by text, assignee, label, or status. Use list_tags to discover valid label values.",
40875
40885
  inputSchema: {
40876
40886
  query: external_exports.string().optional().describe("Text to search for in task content"),
40877
40887
  assignee: external_exports.string().optional().describe("Filter by assignee (without @)"),
@@ -40915,7 +40925,7 @@ function registerTools(server2) {
40915
40925
  });
40916
40926
  server2.registerTool("search_context", {
40917
40927
  title: "Search Context",
40918
- description: "Search for contextual detail (descriptions, acceptance criteria, learnings) across all items. Returns any task with rich content \u2014 broader than find_knowledge which only returns knowledge:true items. Use this for finding implementation details, past decisions, and context before starting work.",
40928
+ description: "Search for contextual detail (descriptions, acceptance criteria, learnings) across all items. Returns any task with rich content \u2014 broader than find_knowledge which only returns knowledge:true items. Use this for finding implementation details, past decisions, and context before starting work. Use list_tags to discover valid label values.",
40919
40929
  inputSchema: {
40920
40930
  query: external_exports.string().optional().describe("Text to search for across descriptions, AC, learnings, and task content"),
40921
40931
  label: external_exports.string().optional().describe("Filter by label (without #). Also matches #tags inside learnings text."),
@@ -40936,14 +40946,18 @@ function registerTools(server2) {
40936
40946
  task.content,
40937
40947
  task.description,
40938
40948
  task.acceptanceCriteria,
40939
- task.learnings
40949
+ task.learnings,
40950
+ ...item.meta?.tags ?? []
40940
40951
  ].filter(Boolean).join(" ").toLowerCase();
40941
40952
  let match = true;
40942
40953
  if (q && !searchable.includes(q)) match = false;
40943
40954
  if (label) {
40944
40955
  const hasLabel = task.metadata.labels.includes(label);
40945
40956
  const hasInlineLabelTag = searchable.includes(`#${label.toLowerCase()}`);
40946
- if (!hasLabel && !hasInlineLabelTag) match = false;
40957
+ const hasFrontmatterTag = item.meta?.tags?.some(
40958
+ (t) => t.toLowerCase() === label.toLowerCase()
40959
+ );
40960
+ if (!hasLabel && !hasInlineLabelTag && !hasFrontmatterTag) match = false;
40947
40961
  }
40948
40962
  const hasContext = task.description || task.acceptanceCriteria || task.learnings;
40949
40963
  if (!hasContext) match = false;
@@ -40974,7 +40988,7 @@ function registerTools(server2) {
40974
40988
  });
40975
40989
  server2.registerTool("list_projects", {
40976
40990
  title: "List Projects",
40977
- description: "List all projects. Returns array of {id, name, color}. Use project id as projectId in create_item or get_project_items."
40991
+ description: "List all projects with their curated tags. Returns array of {id, name, color, tags}. Use project id as projectId in create_item, get_project_items, or list_tags."
40978
40992
  }, async () => {
40979
40993
  try {
40980
40994
  const projects = await api.listProjects();
@@ -41015,9 +41029,23 @@ function registerTools(server2) {
41015
41029
  return errorResponse(err);
41016
41030
  }
41017
41031
  });
41032
+ server2.registerTool("list_tags", {
41033
+ title: "List Tags",
41034
+ description: "Discover available tags/labels before searching or tagging content. Returns curated tags (defined by humans), project-specific tags, and tags already in use across items. ALWAYS call this before inventing new tags \u2014 reuse existing ones to keep the knowledge base consistent.",
41035
+ inputSchema: {
41036
+ projectId: external_exports.string().optional().describe("Optional project ID to scope tags to a specific project")
41037
+ }
41038
+ }, async ({ projectId }) => {
41039
+ try {
41040
+ const result = await api.getTags(projectId);
41041
+ return json2(result);
41042
+ } catch (err) {
41043
+ return errorResponse(err);
41044
+ }
41045
+ });
41018
41046
  server2.registerTool("add_knowledge", {
41019
41047
  title: "Add Knowledge",
41020
- description: "Add a knowledge item. Knowledge items are tasks with knowledge:true \u2014 they store decisions, patterns, references, and institutional memory. They reuse the task infrastructure but skip the checkbox/completion workflow.",
41048
+ description: "Add a knowledge item. Knowledge items are tasks with knowledge:true \u2014 they store decisions, patterns, references, and institutional memory. They reuse the task infrastructure but skip the checkbox/completion workflow. Call list_tags first to reuse existing labels.",
41021
41049
  inputSchema: {
41022
41050
  itemId: external_exports.string().describe("The item ID"),
41023
41051
  columnId: external_exports.string().describe("The column ID"),
@@ -41097,7 +41125,7 @@ function registerTools(server2) {
41097
41125
  });
41098
41126
  server2.registerTool("find_knowledge", {
41099
41127
  title: "Find Knowledge",
41100
- description: "Search specifically for curated knowledge items (knowledge:true) and tasks with captured learnings. Use for institutional decisions, patterns, and reference. For broader task history including descriptions, use search_context instead.",
41128
+ description: "Search specifically for curated knowledge items (knowledge:true) and tasks with captured learnings. Use for institutional decisions, patterns, and reference. For broader task history including descriptions, use search_context instead. Use list_tags to discover valid label values.",
41101
41129
  inputSchema: {
41102
41130
  query: external_exports.string().optional().describe("Text to search for in knowledge items"),
41103
41131
  label: external_exports.string().optional().describe("Filter by label (without #)")
@@ -41120,14 +41148,18 @@ function registerTools(server2) {
41120
41148
  task.content,
41121
41149
  task.description,
41122
41150
  task.acceptanceCriteria,
41123
- task.learnings
41151
+ task.learnings,
41152
+ ...item.meta?.tags ?? []
41124
41153
  ].filter(Boolean).join(" ").toLowerCase();
41125
41154
  if (!searchable.includes(q)) continue;
41126
41155
  }
41127
41156
  if (label) {
41128
41157
  const hasLabel = task.metadata?.labels?.includes(label);
41129
41158
  const hasInlineTag = task.learnings?.toLowerCase().includes(`#${label.toLowerCase()}`);
41130
- if (!hasLabel && !hasInlineTag) continue;
41159
+ const hasFrontmatterTag = item.meta?.tags?.some(
41160
+ (t) => t.toLowerCase() === label.toLowerCase()
41161
+ );
41162
+ if (!hasLabel && !hasInlineTag && !hasFrontmatterTag) continue;
41131
41163
  }
41132
41164
  results.push({
41133
41165
  itemId: itemSummary.id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "automd-mcp",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "MCP server for AutoMD — manage boards, checklists, and pages stored as markdown",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",