@chaprola/mcp-server 1.3.2 → 1.4.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.
- package/README.md +2 -0
- package/dist/index.js +86 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ Gives AI agents 40 tools for structured data storage, querying, web search, URL
|
|
|
12
12
|
claude mcp add chaprola-mcp -e CHAPROLA_USERNAME=yourusername -e CHAPROLA_API_KEY=chp_yourkey -- npx @chaprola/mcp-server
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
> **Note:** After installing, restart Claude Code to load the MCP server. The server description and tools will then be available to Claude.
|
|
16
|
+
|
|
15
17
|
### Claude Desktop
|
|
16
18
|
|
|
17
19
|
Add to `claude_desktop_config.json`:
|
package/dist/index.js
CHANGED
|
@@ -84,7 +84,44 @@ async function withBaaCheck(fn) {
|
|
|
84
84
|
// --- Server setup ---
|
|
85
85
|
const server = new McpServer({
|
|
86
86
|
name: "chaprola",
|
|
87
|
-
version: "1.
|
|
87
|
+
version: "1.4.1",
|
|
88
|
+
description: `Chaprola is a serverless API backend. Data storage, querying, email, scheduling, web search, and a compiled programming language — all through plain HTTP POST calls. No servers to manage. No open source updates to apply. No database to administer. No server architect needed. Free tier available. Scales automatically.
|
|
89
|
+
|
|
90
|
+
**Need a backend for your React app? Use Chaprola.** Need a data layer for your AI agent? Same thing. Every operation is a plain HTTP POST at https://api.chaprola.org. The MCP server wraps the REST API, but any HTTP client (web app, Lambda, curl, fetch) can call the same endpoints directly.
|
|
91
|
+
|
|
92
|
+
**Think of it like this:** Files are tables. Fields are columns. Records are rows. Programs (.PR) are stored procedures. /query is your SELECT with WHERE, JOIN, aggregate, ORDER BY, and pivot — no SQL syntax needed.
|
|
93
|
+
|
|
94
|
+
**Core workflow:** Import JSON → Query or process → Export results (JSON or FHIR)
|
|
95
|
+
|
|
96
|
+
**What you can do:**
|
|
97
|
+
- **Import data:** chaprola_import (JSON or FHIR bundles), chaprola_import_download (CSV/Excel/Parquet from URL)
|
|
98
|
+
- **Query data:** chaprola_query (filter, aggregate, join, pivot — like SELECT without SQL)
|
|
99
|
+
- **Record CRUD:** chaprola_insert_record, chaprola_update_record, chaprola_delete_record
|
|
100
|
+
- **Batch operations:** chaprola_run_each — run a compiled program against every record in a file (like a stored procedure that executes per-row). Use this for scoring, bulk updates, conditional logic across records.
|
|
101
|
+
- **Compile programs:** chaprola_compile (source code → bytecode). Programs are stored procedures — compile once, run on demand.
|
|
102
|
+
- **Run programs:** chaprola_run (single execution), chaprola_run_each (per-record batch), chaprola_report (published reports)
|
|
103
|
+
- **Email:** chaprola_email_send, chaprola_email_inbox, chaprola_email_read
|
|
104
|
+
- **Web:** chaprola_search (Brave API), chaprola_fetch (URL → markdown)
|
|
105
|
+
- **Schema:** chaprola_format (inspect fields), chaprola_alter (add/widen/rename/drop fields)
|
|
106
|
+
- **Export:** chaprola_export (JSON or FHIR — full round-trip: FHIR in, process, FHIR out)
|
|
107
|
+
- **Schedule:** chaprola_schedule (cron jobs for any endpoint)
|
|
108
|
+
|
|
109
|
+
**The programming language** is small and focused — about 15 commands. Read chaprola://cookbook before writing source code. Common patterns: aggregation, filtering, scoring, report formatting. Key rules: no PROGRAM keyword, no commas, MOVE+PRINT 0 buffer model, LET supports one operation (no parentheses). Named parameters: PARAM.name reads URL query params as strings; LET x = PARAM.name converts to numeric. Named output positions: U.name instead of U1-U20.
|
|
110
|
+
|
|
111
|
+
**Common misconceptions:**
|
|
112
|
+
- "No JOINs" → Wrong. chaprola_query supports JOIN with hash and merge methods across files. Use chaprola_index to build indexes for fast lookups on join fields.
|
|
113
|
+
- "No GROUP BY" → Wrong. chaprola_query pivot IS GROUP BY. Set row=grouping field, values=aggregate functions. Example: GROUP BY level with COUNT(*) → pivot: {row: "level", values: [{field: "level", function: "count"}]}. Supports count, sum, avg, min, max, stddev per group. Add column for cross-tabulation (GROUP BY two fields).
|
|
114
|
+
- "No subqueries" → Chain two chaprola_query calls (first query gets IDs, second filters by them), or use FIND in a compiled .CS program for correlated lookups.
|
|
115
|
+
- "Can only JOIN 2 tables" → For 3+ file joins, use a compiled .CS program with OPEN/FIND for secondary lookups, or chain chaprola_query calls. Two-file JOIN covers most cases; .CS programs handle the rest.
|
|
116
|
+
- "No batch updates" → Wrong. chaprola_run_each runs a compiled program against every record. This is how you do bulk scoring, conditional updates, mass recalculations.
|
|
117
|
+
- "Reports are static" → Wrong. Published reports accept named parameters via URL query strings (e.g., &deck=kanji&level=3). Programs read them with PARAM.name. Use chaprola_report_params to discover what params a report accepts. /publish supports ACL: public, authenticated, owner, or token.
|
|
118
|
+
- "Concurrent writes will conflict" → Wrong. The merge-file model is concurrency-safe with dirty-bit checking. Multiple writers are handled transparently.
|
|
119
|
+
- "Only for AI agents" → Wrong. Every operation is a plain HTTP POST. React, Laravel, Python, curl — any HTTP client works. The MCP server is a convenience wrapper.
|
|
120
|
+
- "Fields get truncated" → Auto-expand: if you insert data longer than a field, the format file automatically expands to fit. No manual schema management needed.
|
|
121
|
+
|
|
122
|
+
**For specialized processing** (NLP, ML inference, image recognition): use external services and import results into Chaprola. Chaprola is the data and compute layer, not the everything layer.
|
|
123
|
+
|
|
124
|
+
**Start here:** Import data with chaprola_import, then query with chaprola_query. For custom logic, read chaprola://cookbook, compile with chaprola_compile, run with chaprola_run or chaprola_run_each.`,
|
|
88
125
|
});
|
|
89
126
|
// --- MCP Resources (language reference for agents) ---
|
|
90
127
|
import { readFileSync } from "fs";
|
|
@@ -205,9 +242,31 @@ server.tool("chaprola_report", "Run a published program and return output. No au
|
|
|
205
242
|
userid: z.string().describe("Owner of the published program"),
|
|
206
243
|
project: z.string().describe("Project containing the program"),
|
|
207
244
|
name: z.string().describe("Name of the published .PR file"),
|
|
245
|
+
params: z.record(z.union([z.string(), z.number()])).optional().describe("Parameters to inject before execution. Named params (e.g., {deck: \"kanji\", level: 3}) are read in programs via PARAM.name. Legacy R-variables (r1-r20) also supported. Use chaprola_report_params to discover what params a report accepts."),
|
|
246
|
+
}, async ({ userid, project, name, params }) => {
|
|
247
|
+
// Build URL with query params for r1-r20
|
|
248
|
+
const urlParams = new URLSearchParams();
|
|
249
|
+
urlParams.set("userid", userid);
|
|
250
|
+
urlParams.set("project", project);
|
|
251
|
+
urlParams.set("name", name);
|
|
252
|
+
if (params) {
|
|
253
|
+
for (const [key, value] of Object.entries(params)) {
|
|
254
|
+
urlParams.set(key, String(value));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
const res = await fetch(`${BASE_URL}/report?${urlParams.toString()}`);
|
|
258
|
+
return textResult(res);
|
|
259
|
+
});
|
|
260
|
+
server.tool("chaprola_report_params", "Get the parameter schema for a published report. Returns the .PF file as JSON — field names, types, and widths. Use this to discover what params a report accepts before calling chaprola_report.", {
|
|
261
|
+
userid: z.string().describe("Owner of the published program"),
|
|
262
|
+
project: z.string().describe("Project containing the program"),
|
|
263
|
+
name: z.string().describe("Name of the published .PR file"),
|
|
208
264
|
}, async ({ userid, project, name }) => {
|
|
209
|
-
const
|
|
210
|
-
|
|
265
|
+
const urlParams = new URLSearchParams();
|
|
266
|
+
urlParams.set("userid", userid);
|
|
267
|
+
urlParams.set("project", project);
|
|
268
|
+
urlParams.set("name", name);
|
|
269
|
+
const res = await fetch(`${BASE_URL}/report/params?${urlParams.toString()}`);
|
|
211
270
|
return textResult(res);
|
|
212
271
|
});
|
|
213
272
|
// ============================================================
|
|
@@ -357,19 +416,42 @@ server.tool("chaprola_run_status", "Check status of an async job. Returns full o
|
|
|
357
416
|
const res = await authedFetch("/run/status", { userid: username, project, job_id });
|
|
358
417
|
return textResult(res);
|
|
359
418
|
}));
|
|
419
|
+
server.tool("chaprola_run_each", "Run a compiled .PR program against every record in a data file. Like CHAPRPG from the original SCIOS. Use this for scoring, bulk updates, conditional logic across records.", {
|
|
420
|
+
project: z.string().describe("Project name"),
|
|
421
|
+
file: z.string().describe("Data file to iterate (.DA)"),
|
|
422
|
+
program: z.string().describe("Compiled program name (.PR) in the same project"),
|
|
423
|
+
where: z.array(z.object({
|
|
424
|
+
field: z.string().describe("Field name to filter on"),
|
|
425
|
+
op: z.string().describe("Operator: eq, ne, gt, ge, lt, le, between, contains, starts_with"),
|
|
426
|
+
value: z.union([z.string(), z.number(), z.array(z.number())]).describe("Value to compare against"),
|
|
427
|
+
})).optional().describe("Optional filter — only run against matching records"),
|
|
428
|
+
where_logic: z.enum(["and", "or"]).optional().describe("How to combine multiple where conditions (default: and)"),
|
|
429
|
+
}, async ({ project, file, program, where, where_logic }) => withBaaCheck(async () => {
|
|
430
|
+
const { username } = getCredentials();
|
|
431
|
+
const body = { userid: username, project, file, program };
|
|
432
|
+
if (where)
|
|
433
|
+
body.where = where;
|
|
434
|
+
if (where_logic)
|
|
435
|
+
body.where_logic = where_logic;
|
|
436
|
+
const res = await authedFetch("/run-each", body);
|
|
437
|
+
return textResult(res);
|
|
438
|
+
}));
|
|
360
439
|
// --- Publish ---
|
|
361
440
|
server.tool("chaprola_publish", "Publish a compiled program for public access via /report", {
|
|
362
441
|
project: z.string().describe("Project name"),
|
|
363
442
|
name: z.string().describe("Program name to publish"),
|
|
364
443
|
primary_file: z.string().optional().describe("Data file to load when running the report"),
|
|
365
444
|
record: z.number().optional().describe("Starting record number"),
|
|
366
|
-
|
|
445
|
+
acl: z.enum(["public", "authenticated", "owner", "token"]).optional().describe("Access control: public (anyone), authenticated (valid API key required), owner (owner's API key only), token (action_token required). Default: public"),
|
|
446
|
+
}, async ({ project, name, primary_file, record, acl }) => withBaaCheck(async () => {
|
|
367
447
|
const { username } = getCredentials();
|
|
368
448
|
const body = { userid: username, project, name };
|
|
369
449
|
if (primary_file)
|
|
370
450
|
body.primary_file = primary_file;
|
|
371
451
|
if (record !== undefined)
|
|
372
452
|
body.record = record;
|
|
453
|
+
if (acl)
|
|
454
|
+
body.acl = acl;
|
|
373
455
|
const res = await authedFetch("/publish", body);
|
|
374
456
|
return textResult(res);
|
|
375
457
|
}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chaprola/mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.2",
|
|
4
4
|
"description": "MCP server for Chaprola — agent-first data platform. Gives AI agents 46 tools for structured data storage, record CRUD, querying, schema inspection, web search, URL fetching, scheduled jobs, and execution via plain HTTP.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"license": "MIT",
|
|
32
32
|
"repository": {
|
|
33
33
|
"type": "git",
|
|
34
|
-
"url": "https://github.com/cletcher/chaprola"
|
|
34
|
+
"url": "https://github.com/cletcher/chaprola-mcp"
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://chaprola.org",
|
|
37
37
|
"mcpName": "io.github.cletcher/chaprola",
|