@live-context/mcp 0.7.1 → 0.9.0

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 (3) hide show
  1. package/README.md +32 -0
  2. package/dist/index.js +100 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -30,6 +30,38 @@ For Claude Desktop, Cursor, or any other MCP client, add this to your `mcpServer
30
30
  }
31
31
  ```
32
32
 
33
+ ## Remote (HTTP) transport
34
+
35
+ Live Context also exposes a [Streamable HTTP MCP transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#streamable-http) at `https://live-context.com/api/mcp/mcp`. Use this when you'd rather not install Node — Claude Code, Cursor, Codex CLI, and ChatGPT Developer Mode all support paste-in URLs with custom headers.
36
+
37
+ **Claude Code remote:**
38
+
39
+ ```bash
40
+ claude mcp add --transport http live-context https://live-context.com/api/mcp/mcp \
41
+ --header "Authorization: Bearer <your-team-key>" \
42
+ --header "X-LC-User-Token: <your-user-token>"
43
+ ```
44
+
45
+ **Cursor / Claude Desktop / any "URL + headers" client:**
46
+
47
+ ```json
48
+ {
49
+ "mcpServers": {
50
+ "live-context": {
51
+ "url": "https://live-context.com/api/mcp/mcp",
52
+ "headers": {
53
+ "Authorization": "Bearer <your-team-key>",
54
+ "X-LC-User-Token": "<your-user-token>"
55
+ }
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ The HTTP endpoint is authenticated with the same team key + (optional) user token as the stdio proxy. Both transports talk to the same backend and expose the same tools.
62
+
63
+ A dashboard-driven one-click install flow (OAuth-based — no token pasting) is on the way; until then, the snippets above are the canonical Remote setup.
64
+
33
65
  ## Environment variables
34
66
 
35
67
  | Variable | Required | Purpose |
package/dist/index.js CHANGED
@@ -91,7 +91,7 @@ async function callMcpApi(tool, args, method = 'POST') {
91
91
  // ---------------------------------------------------------------------------
92
92
  const server = new McpServer({
93
93
  name: 'live-context-mcp',
94
- version: '0.7.1', // 0.7.0 added body_tiptap; 0.7.1 adds width_mode (fixed | wide)
94
+ version: '0.9.0', // 0.9.0 adds Projects MLP ticket tools (list_my_tasks, get_ticket, create_ticket, update_ticket_status, comment_on_ticket, list_my_reviews, claim_review, assign_ticket, link_ticket)
95
95
  });
96
96
  server.registerTool('get_context', {
97
97
  description: 'Retrieve relevant context entries. Returns L0 summaries (title, type, snippet) by default. Pass drawer_id to get full page body.',
@@ -311,6 +311,105 @@ server.registerTool('get_page', {
311
311
  page_id: z.string().describe('Page id (from list_pages or write_page result).'),
312
312
  },
313
313
  }, (args) => callMcpApi('get-page', args));
314
+ server.registerTool('ask', {
315
+ description: 'Ask the live-context brain a question. Returns hybrid-search retrieval (drawers + pages) with ratification metadata and — for contested cases — raw evidence (recency delta, citation counts, author agent, evidence-for counts). The server does NOT synthesize a prose answer; the calling agent reasons over the structured result. Requires X-LC-User-Token.',
316
+ inputSchema: {
317
+ question: z.string().min(1).describe('The question to ask the team brain.'),
318
+ limit: z
319
+ .number()
320
+ .int()
321
+ .min(1)
322
+ .max(50)
323
+ .optional()
324
+ .describe('Max candidates returned (default 8, max 50)'),
325
+ },
326
+ }, (args) => callMcpApi('ask', args));
327
+ // ---------------------------------------------------------------------------
328
+ // Projects MLP — ticket tools (mig 056/057/058). All require a user token
329
+ // (LC_USER_TOKEN). Actor resolution (agent vs member) happens server-side from
330
+ // the token's agent binding; the proxy just forwards args.
331
+ // ---------------------------------------------------------------------------
332
+ server.registerTool('list_my_tasks', {
333
+ description: 'List the tickets assigned to you as the executor (the actor to do the work). The actor is the agent when called with an agent-bound token, otherwise the human member. Optionally filter by status. Use get_ticket for the full body, links, and comments.',
334
+ inputSchema: {
335
+ status: z
336
+ .enum(['backlog', 'ready', 'in_progress', 'in_review', 'done'])
337
+ .optional()
338
+ .describe('Filter to tickets in this status. Omit to return all of your tasks.'),
339
+ },
340
+ }, (args) => callMcpApi('list-my-tasks', args));
341
+ server.registerTool('get_ticket', {
342
+ description: 'Fetch a single ticket by id. Returns title, body, status, workstream + project, executor/reviewer assignment, links to drawers/pages, timestamps, and the full comment thread. Call this before updating status or commenting so you act on current state.',
343
+ inputSchema: {
344
+ ticket_id: z.string().describe('Ticket id (from list_my_tasks, list_my_reviews, or create_ticket).'),
345
+ },
346
+ }, (args) => callMcpApi('get-ticket', args));
347
+ server.registerTool('create_ticket', {
348
+ description: 'Create a new ticket inside a workstream. Returns the new ticket id. Defaults to backlog status. Use list_context / project tooling to find the target workstream_id first.',
349
+ inputSchema: {
350
+ workstream_id: z.string().describe('Workstream the ticket belongs to.'),
351
+ title: z.string().describe('Short, action-oriented ticket title.'),
352
+ body: z.string().optional().describe('Optional detailed description / acceptance criteria.'),
353
+ status: z
354
+ .enum(['backlog', 'ready', 'in_progress', 'in_review', 'done'])
355
+ .optional()
356
+ .describe("Initial status. Defaults to 'backlog'."),
357
+ },
358
+ }, (args) => callMcpApi('create-ticket', args));
359
+ server.registerTool('update_ticket_status', {
360
+ description: "Move a ticket to a new status. If you request 'done' on a ticket that has a reviewer, the server rewrites it to 'in_review' and submits it for review instead of closing it — the result includes rewritten=true and a message explaining this. Always inspect the returned status vs requested_status.",
361
+ inputSchema: {
362
+ ticket_id: z.string().describe('Ticket to transition.'),
363
+ status: z
364
+ .enum(['backlog', 'ready', 'in_progress', 'in_review', 'done'])
365
+ .describe('Desired status. May be rewritten to in_review when a reviewer is assigned.'),
366
+ },
367
+ }, (args) => callMcpApi('update-ticket-status', args));
368
+ server.registerTool('comment_on_ticket', {
369
+ description: 'Add a comment to a ticket. The comment is attributed to you (agent or member). Returns the new comment id. Use this to record progress, hand-off notes, or review feedback.',
370
+ inputSchema: {
371
+ ticket_id: z.string().describe('Ticket to comment on.'),
372
+ body: z.string().describe('Comment text.'),
373
+ },
374
+ }, (args) => callMcpApi('comment-on-ticket', args));
375
+ server.registerTool('list_my_reviews', {
376
+ description: 'List tickets awaiting your review (where you are the assigned reviewer, or which are open for review claiming). The actor is the agent or human member. Use claim_review to take an unclaimed review and get_ticket for details.',
377
+ inputSchema: {},
378
+ }, (args) => callMcpApi('list-my-reviews', args));
379
+ server.registerTool('claim_review', {
380
+ description: 'Claim the reviewer slot on a ticket that is open for review, assigning yourself (agent or member) as its reviewer. Returns the updated ticket. Use list_my_reviews to find claimable tickets.',
381
+ inputSchema: {
382
+ ticket_id: z.string().describe('Ticket to claim review on.'),
383
+ },
384
+ }, (args) => callMcpApi('claim-review', args));
385
+ server.registerTool('assign_ticket', {
386
+ description: 'Set or change a ticket\'s executor and/or reviewer. Each side is an actor (kind + id) — kind is "member" (a user id) or "agent" (an agent id). Pass only the side(s) you want to change. The executor and reviewer must differ; assigning the same actor to both is rejected with executor_equals_reviewer.',
387
+ inputSchema: {
388
+ ticket_id: z.string().describe('Ticket to (re)assign.'),
389
+ executor_kind: z
390
+ .enum(['member', 'agent'])
391
+ .optional()
392
+ .describe('Executor actor kind. Provide together with executor_id.'),
393
+ executor_id: z.string().optional().describe('Executor actor id (user id or agent id).'),
394
+ reviewer_kind: z
395
+ .enum(['member', 'agent'])
396
+ .optional()
397
+ .describe('Reviewer actor kind. Provide together with reviewer_id.'),
398
+ reviewer_id: z.string().optional().describe('Reviewer actor id (user id or agent id).'),
399
+ },
400
+ }, (args) => callMcpApi('assign-ticket', args));
401
+ server.registerTool('link_ticket', {
402
+ description: "Link a ticket to a drawer or a page as supporting context. Provide exactly one of drawer_id or page_id. relation_kind labels the relationship and defaults to 'relates_to'.",
403
+ inputSchema: {
404
+ ticket_id: z.string().describe('Ticket to link from.'),
405
+ drawer_id: z.string().optional().describe('Drawer (context entry) id to link to.'),
406
+ page_id: z.string().optional().describe('Page id to link to.'),
407
+ relation_kind: z
408
+ .string()
409
+ .optional()
410
+ .describe("Relationship label. Defaults to 'relates_to'."),
411
+ },
412
+ }, (args) => callMcpApi('link-ticket', args));
314
413
  server.registerTool('health_check', {
315
414
  description: 'Returns server health status and resolved team identity',
316
415
  }, () => callMcpApi('health-check', undefined, 'GET'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-context/mcp",
3
- "version": "0.7.1",
3
+ "version": "0.9.0",
4
4
  "private": false,
5
5
  "description": "Live Context MCP — stdio proxy to live-context.com hosted API. Customer-side has no Supabase dependency.",
6
6
  "type": "module",