@chaprola/mcp-server 1.10.0 → 1.11.1

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 +14 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -509,9 +509,10 @@ server.tool("chaprola_systemhelp", "Send your program name and error message. Ch
509
509
  name: z.string().describe("Program name (without extension)"),
510
510
  error: z.string().optional().describe("Error message from compile or runtime (copy verbatim if available)"),
511
511
  request: z.string().describe("Plain-language description of the problem. Include context: what changed, what you expected, what happened instead."),
512
- }, async ({ project, name, error, request }) => withBaaCheck(async () => {
512
+ userid: z.string().optional().describe("Project owner's username. Required when accessing a shared project where you are a writer. Defaults to the authenticated user."),
513
+ }, async ({ project, name, error, request, userid }) => withBaaCheck(async () => {
513
514
  const { username } = getCredentials();
514
- const body = { userid: username, project, name, request };
515
+ const body = { userid: userid || username, project, name, request };
515
516
  if (error)
516
517
  body.error = error;
517
518
  const res = await authedFetch("/systemhelp", body);
@@ -582,23 +583,26 @@ server.tool("chaprola_download", "Get a presigned S3 URL to download any file yo
582
583
  return textResult(res);
583
584
  }));
584
585
  // --- Query ---
585
- server.tool("chaprola_query", "SQL-free data query with WHERE, SELECT, aggregation, ORDER BY, JOIN, pivot, and Mercury scoring", {
586
+ server.tool("chaprola_query", "SQL-free data query with WHERE, SELECT, aggregation, ORDER BY, JOIN, pivot, DISTINCT, transforms, and Mercury scoring", {
586
587
  project: z.string().describe("Project name"),
587
588
  file: z.string().describe("Data file to query"),
588
- where: z.string().optional().describe("JSON object of filter conditions, e.g. {\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}. Ops: eq, ne, gt, ge, lt, le, between, contains, starts_with, in, not_in. For in/not_in, value must be a JSON array of strings, e.g. {\"field\": \"status\", \"op\": \"in\", \"value\": [\"active\", \"pending\"]}"),
589
+ where: z.string().optional().describe("JSON array of filter conditions, e.g. [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"active\"}]. Ops: eq, ne, gt, ge, lt, le, between, contains, starts_with, in, not_in, date_within, date_before, date_after. For in/not_in, value is a JSON array. For date_within, value is relative like \"30d\", \"6h\", \"15m\"."),
589
590
  select: z.array(z.string()).optional().describe("Fields to include in output"),
590
591
  aggregate: z.string().optional().describe("JSON array of aggregation specs, e.g. [{\"field\": \"amount\", \"func\": \"sum\"}]. Funcs: count, sum, avg, min, max, stddev"),
591
- order_by: z.string().optional().describe("JSON array of sort specs, e.g. [{\"field\": \"name\", \"dir\": \"asc\"}]"),
592
+ order_by: z.string().optional().describe("JSON sort spec — single object or array for multi-column sort, e.g. [{\"field\": \"dept\", \"dir\": \"asc\"}, {\"field\": \"salary\", \"dir\": \"desc\"}]"),
593
+ distinct: z.boolean().optional().describe("Return only unique rows based on selected fields. Cannot combine with aggregate or pivot."),
594
+ transform: z.string().optional().describe("JSON array of transforms applied before WHERE, e.g. [{\"field\": \"email\", \"func\": \"lower\"}]. Funcs: upper, lower, trim, substring (start, length), replace (old, new), length, date_trunc (unit: year/month/day/hour), date_extract (part: year/month/day/hour/minute/weekday)"),
592
595
  limit: z.number().optional().describe("Max results to return"),
593
596
  offset: z.number().optional().describe("Skip this many results"),
594
597
  join: z.string().optional().describe("JSON object of join config, e.g. {\"file\": \"other\", \"on\": \"id\", \"type\": \"inner\"}"),
595
598
  pivot: z.string().optional().describe("JSON object of pivot config, e.g. {\"row\": \"category\", \"column\": \"month\", \"values\": \"sales\"}"),
596
599
  mercury: z.string().optional().describe("JSON object of mercury scoring config, e.g. {\"fields\": [{\"field\": \"score\", \"target\": 100, \"weight\": 1.0}]}"),
597
600
  userid: z.string().optional().describe("Project owner's username. Required when accessing a shared project where you are a writer. Defaults to the authenticated user."),
598
- }, async ({ project, file, where: whereStr, select, aggregate: aggregateStr, order_by: orderByStr, limit, offset, join: joinStr, pivot: pivotStr, mercury: mercuryStr, userid }) => withBaaCheck(async () => {
601
+ }, async ({ project, file, where: whereStr, select, aggregate: aggregateStr, order_by: orderByStr, distinct, transform: transformStr, limit, offset, join: joinStr, pivot: pivotStr, mercury: mercuryStr, userid }) => withBaaCheck(async () => {
599
602
  const where = typeof whereStr === 'string' ? JSON.parse(whereStr) : whereStr;
600
603
  const aggregate = typeof aggregateStr === 'string' ? JSON.parse(aggregateStr) : aggregateStr;
601
604
  const order_by = typeof orderByStr === 'string' ? JSON.parse(orderByStr) : orderByStr;
605
+ const transform = transformStr ? (typeof transformStr === 'string' ? JSON.parse(transformStr) : transformStr) : undefined;
602
606
  const join = typeof joinStr === 'string' ? JSON.parse(joinStr) : joinStr;
603
607
  const pivot = typeof pivotStr === 'string' ? JSON.parse(pivotStr) : pivotStr;
604
608
  const mercury = typeof mercuryStr === 'string' ? JSON.parse(mercuryStr) : mercuryStr;
@@ -612,6 +616,10 @@ server.tool("chaprola_query", "SQL-free data query with WHERE, SELECT, aggregati
612
616
  body.aggregate = aggregate;
613
617
  if (order_by)
614
618
  body.order_by = order_by;
619
+ if (distinct)
620
+ body.distinct = distinct;
621
+ if (transform)
622
+ body.transform = transform;
615
623
  if (limit !== undefined)
616
624
  body.limit = limit;
617
625
  if (offset !== undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chaprola/mcp-server",
3
- "version": "1.10.0",
3
+ "version": "1.11.1",
4
4
  "description": "MCP server for Chaprola — agent-first data platform. Gives AI agents tools for structured data storage, record CRUD, querying, schema inspection, documentation lookup, web search, URL fetching, scheduled jobs, scoped site keys, and execution via plain HTTP.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",