@ratifia/mcp 0.11.0 → 0.12.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.
- package/README.md +2 -2
- package/dist/index.js +25 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,8 +57,8 @@ real decisions. CI runs it on every push.
|
|
|
57
57
|
| `RATIFIA_API_KEY` | ✅ | — | Org-scoped worker API key. |
|
|
58
58
|
| `RATIFIA_API_URL` | | `https://api.ratifia.com` | Ratifia API base. |
|
|
59
59
|
| `RATIFIA_APP_URL` | | `https://app.ratifia.com` | Dashboard base for decision links. |
|
|
60
|
-
| `RATIFIA_APPROVER_EMAIL` | | — |
|
|
61
|
-
| `RATIFIA_POLICY` | | — | The **key** of a policy deciding **who** reviews
|
|
60
|
+
| `RATIFIA_APPROVER_EMAIL` | | — | Without a policy: who can answer, one email or a comma-separated list. Ignored when `RATIFIA_POLICY` is set. |
|
|
61
|
+
| `RATIFIA_POLICY` | | — | The **key** of a policy deciding **who** reviews, the quorum they need, and the expiry (`timeout_minutes` is then not sent). It must exist in your org: an unknown key is a tool error, and the `gate` hook denies. |
|
|
62
62
|
| `RATIFIA_GATE_INCLUDE_PROMPT` | | off | `gate` hook only: `1` includes the user's last request (from the transcript) in the decision. Off by default — the gate otherwise sends only metadata, never your conversation. |
|
|
63
63
|
| `RATIFIA_WORKFLOW` | | `ratifia-mcp` (`ratifia-gate` for the hook) | The **workflow** decisions are filed under — the category the dashboard's Workflow filter groups by, e.g. `deploys` or `billing-agent`. A `request_decision` call can override it. |
|
|
64
64
|
|
package/dist/index.js
CHANGED
|
@@ -24,8 +24,11 @@
|
|
|
24
24
|
* RATIFIA_API_URL API base (default https://api.ratifia.com)
|
|
25
25
|
* RATIFIA_API_KEY org-scoped worker API key (required)
|
|
26
26
|
* RATIFIA_APP_URL dashboard base for the decision link (default https://app.ratifia.com)
|
|
27
|
-
* RATIFIA_APPROVER_EMAIL who
|
|
28
|
-
*
|
|
27
|
+
* RATIFIA_APPROVER_EMAIL who may answer (comma-separated for several); used only
|
|
28
|
+
* when RATIFIA_POLICY is unset
|
|
29
|
+
* RATIFIA_POLICY optional: policy key (must exist in the org). When set, the
|
|
30
|
+
* policy decides who approves and when it expires, and
|
|
31
|
+
* RATIFIA_APPROVER_EMAIL / timeout_minutes are not sent
|
|
29
32
|
* (e.g. a route to your phone)
|
|
30
33
|
* RATIFIA_GATE_INCLUDE_PROMPT gate hook only: 1 = include the user's last request from the
|
|
31
34
|
* transcript in the decision (off by default — it is case content)
|
|
@@ -42,8 +45,21 @@ import { z } from 'zod';
|
|
|
42
45
|
const API_URL = (process.env.RATIFIA_API_URL ?? 'https://api.ratifia.com').replace(/\/+$/, '');
|
|
43
46
|
const API_KEY = process.env.RATIFIA_API_KEY;
|
|
44
47
|
const APP_URL = (process.env.RATIFIA_APP_URL ?? 'https://app.ratifia.com').replace(/\/+$/, '');
|
|
45
|
-
const
|
|
46
|
-
|
|
48
|
+
const APPROVERS = (process.env.RATIFIA_APPROVER_EMAIL ?? '')
|
|
49
|
+
.split(',')
|
|
50
|
+
.map((s) => s.trim())
|
|
51
|
+
.filter(Boolean);
|
|
52
|
+
const POLICY = process.env.RATIFIA_POLICY || undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Who answers (Ratifia PD-003): a policy owns its approvers and expiry, so with
|
|
55
|
+
* one set only its key is sent (approvers alongside it are refused, 422
|
|
56
|
+
* field_owned_by_policy). Without one, the decision is ad hoc to APPROVERS.
|
|
57
|
+
*/
|
|
58
|
+
const WHO = POLICY
|
|
59
|
+
? { policy: { key: POLICY } }
|
|
60
|
+
: APPROVERS.length
|
|
61
|
+
? { approvers: APPROVERS }
|
|
62
|
+
: {};
|
|
47
63
|
const WORKFLOW = process.env.RATIFIA_WORKFLOW;
|
|
48
64
|
/**
|
|
49
65
|
* Where a decision is filed. `workflowRef` is the category (the dashboard's
|
|
@@ -410,8 +426,7 @@ async function runGate() {
|
|
|
410
426
|
externalRunId,
|
|
411
427
|
stepRef: `tool:${toolName}`.slice(0, 80),
|
|
412
428
|
workflowRef: label(WORKFLOW, 'ratifia-gate', 100),
|
|
413
|
-
...
|
|
414
|
-
...(POLICY ? { policy: POLICY } : {}),
|
|
429
|
+
...WHO,
|
|
415
430
|
required: true,
|
|
416
431
|
context: {
|
|
417
432
|
prompt: `An agent wants to run the tool "${toolName}"${where ? ` in ${where}` : ''}. Approve?`,
|
|
@@ -493,7 +508,7 @@ server.registerTool('request_decision', {
|
|
|
493
508
|
.int()
|
|
494
509
|
.positive()
|
|
495
510
|
.optional()
|
|
496
|
-
.describe(
|
|
511
|
+
.describe("Auto-expire (and reject) if unanswered after N minutes. Omit to wait indefinitely. Ignored when this server is configured with a policy (RATIFIA_POLICY): the policy's expiry applies."),
|
|
497
512
|
response_type: z
|
|
498
513
|
.enum(['approval', 'select', 'text'])
|
|
499
514
|
.optional()
|
|
@@ -575,10 +590,10 @@ server.registerTool('request_decision', {
|
|
|
575
590
|
externalRunId,
|
|
576
591
|
stepRef: label(step, title, 80),
|
|
577
592
|
workflowRef: label(workflow, label(WORKFLOW, 'ratifia-mcp', 100), 100),
|
|
578
|
-
...
|
|
579
|
-
...(POLICY ? { policy: POLICY } : {}),
|
|
593
|
+
...WHO,
|
|
580
594
|
required: true,
|
|
581
|
-
|
|
595
|
+
// With a policy, the policy sets the expiry (a timeoutSec would be refused).
|
|
596
|
+
...(timeout_minutes && !POLICY ? { timeoutSec: timeout_minutes * 60 } : {}),
|
|
582
597
|
...(responseSpec ? { responseSpec } : {}),
|
|
583
598
|
...(proposed_output
|
|
584
599
|
? { proposedOutput: { title: proposed_output.title, format: 'text', content: proposed_output.content } }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ratifia/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Ratifia MCP server — let an AI agent request a human decision/approval (HITL) mid-task and resume once it's answered. The agent becomes a Ratifia 'engine'.",
|
|
6
6
|
"keywords": [
|