@heisee/letsclarify-mcp 1.0.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 ADDED
@@ -0,0 +1,48 @@
1
+ # @heisee/letsclarify-mcp
2
+
3
+ MCP server for [LetsClarify](https://letsclarify.ai) — Human-in-the-Loop API for AI agents.
4
+
5
+ Create structured forms via API, share URLs with humans, get JSON back.
6
+
7
+ ## Setup
8
+
9
+ ```json
10
+ {
11
+ "mcpServers": {
12
+ "letsclarify": {
13
+ "command": "npx",
14
+ "args": ["-y", "@heisee/letsclarify-mcp"],
15
+ "env": {
16
+ "LETSCLARIFY_API_KEY": "lc_your_key_here"
17
+ }
18
+ }
19
+ }
20
+ }
21
+ ```
22
+
23
+ ## Tools
24
+
25
+ | Tool | Description |
26
+ |------|-------------|
27
+ | `create_form` | Create a form with schema, title, context, recipients |
28
+ | `get_form_summary` | Quick overview: submitted/pending counts |
29
+ | `get_form_results` | Paginated results with filters and file support |
30
+ | `delete_form` | Permanently delete a form and all its data |
31
+ | `add_recipients` | Add more recipient slots to an existing form |
32
+
33
+ ## Resources
34
+
35
+ | URI | Description |
36
+ |-----|-------------|
37
+ | `letsclarify://schema-dsl` | Schema DSL reference (field types, validation, file config) |
38
+
39
+ ## Environment Variables
40
+
41
+ | Variable | Required | Description |
42
+ |----------|----------|-------------|
43
+ | `LETSCLARIFY_API_KEY` | Yes | API key (starts with `lc_`) |
44
+ | `LETSCLARIFY_BASE_URL` | No | Override base URL (default: `https://letsclarify.ai`) |
45
+
46
+ ## License
47
+
48
+ MIT
@@ -0,0 +1,61 @@
1
+ export interface ApiError {
2
+ error: string;
3
+ message?: string;
4
+ messages?: string[];
5
+ }
6
+ export declare class LetsClarifyClient {
7
+ private baseUrl;
8
+ private apiKey;
9
+ constructor(apiKey: string, baseUrl?: string);
10
+ private request;
11
+ createForm(body: {
12
+ schema: unknown[];
13
+ title?: string;
14
+ context_markdown?: string;
15
+ recipient_count?: number;
16
+ retention_days?: number;
17
+ webhook_url?: string;
18
+ theme_color?: string;
19
+ }): Promise<{
20
+ form_token: string;
21
+ delete_token: string;
22
+ base_url_template: string;
23
+ poll_url: string;
24
+ summary_url: string;
25
+ delete_url: string;
26
+ recipients: string[];
27
+ }>;
28
+ getFormSummary(formToken: string): Promise<{
29
+ expired: boolean;
30
+ known_total: number;
31
+ submitted_total: number;
32
+ pending_total: number;
33
+ updated_at_max: string;
34
+ }>;
35
+ getFormResults(formToken: string, params?: {
36
+ limit?: string;
37
+ cursor?: string;
38
+ status?: string;
39
+ updated_since?: string;
40
+ include_files?: string;
41
+ }): Promise<{
42
+ expired: boolean;
43
+ next_cursor: string | null;
44
+ server_time: string;
45
+ results: Array<{
46
+ recipient_uuid: string;
47
+ status: string;
48
+ submitted_at: string | null;
49
+ updated_at: string;
50
+ response_json: Record<string, unknown> | null;
51
+ files?: unknown;
52
+ }>;
53
+ }>;
54
+ deleteForm(formToken: string, deleteToken: string): Promise<{
55
+ deleted: boolean;
56
+ }>;
57
+ addRecipients(formToken: string, count?: number): Promise<{
58
+ recipients: string[];
59
+ }>;
60
+ }
61
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM,EAAE,OAAO,SAA2B;YAKhD,OAAO;IAiDf,UAAU,CAAC,IAAI,EAAE;QACrB,MAAM,EAAE,OAAO,EAAE,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB;oBAEe,MAAM;sBACJ,MAAM;2BACD,MAAM;kBACf,MAAM;qBACH,MAAM;oBACP,MAAM;oBACN,MAAM,EAAE;;IAIlB,cAAc,CAAC,SAAS,EAAE,MAAM;iBAEzB,OAAO;qBACH,MAAM;yBACF,MAAM;uBACR,MAAM;wBACL,MAAM;;IAIpB,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB;iBAGU,OAAO;qBACH,MAAM,GAAG,IAAI;qBACb,MAAM;iBACV,KAAK,CAAC;YACb,cAAc,EAAE,MAAM,CAAC;YACvB,MAAM,EAAE,MAAM,CAAC;YACf,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;YAC5B,UAAU,EAAE,MAAM,CAAC;YACnB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;YAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;SACjB,CAAC;;IAIA,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;iBACtB,OAAO;;IAOlC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;oBACjB,MAAM,EAAE;;CAM7C"}
@@ -0,0 +1,57 @@
1
+ export class LetsClarifyClient {
2
+ baseUrl;
3
+ apiKey;
4
+ constructor(apiKey, baseUrl = "https://letsclarify.ai") {
5
+ this.apiKey = apiKey;
6
+ this.baseUrl = baseUrl.replace(/\/+$/, "");
7
+ }
8
+ async request(method, path, options = {}) {
9
+ const url = new URL(`${this.baseUrl}${path}`);
10
+ if (options.params) {
11
+ for (const [key, value] of Object.entries(options.params)) {
12
+ if (value !== undefined) {
13
+ url.searchParams.set(key, value);
14
+ }
15
+ }
16
+ }
17
+ const headers = {
18
+ Authorization: `Bearer ${this.apiKey}`,
19
+ Accept: "application/json",
20
+ ...options.headers,
21
+ };
22
+ if (options.body) {
23
+ headers["Content-Type"] = "application/json";
24
+ }
25
+ const response = await fetch(url.toString(), {
26
+ method,
27
+ headers,
28
+ body: options.body ? JSON.stringify(options.body) : undefined,
29
+ });
30
+ const json = await response.json();
31
+ if (!response.ok) {
32
+ const err = json;
33
+ const detail = err.messages
34
+ ? err.messages.join("; ")
35
+ : err.message || err.error;
36
+ throw new Error(`API ${response.status}: ${detail}`);
37
+ }
38
+ return json;
39
+ }
40
+ // --- Public methods ---
41
+ async createForm(body) {
42
+ return this.request("POST", "/api/v1/forms", { body });
43
+ }
44
+ async getFormSummary(formToken) {
45
+ return this.request("GET", `/api/v1/forms/${formToken}/summary`);
46
+ }
47
+ async getFormResults(formToken, params) {
48
+ return this.request("GET", `/api/v1/forms/${formToken}/results`, { params });
49
+ }
50
+ async deleteForm(formToken, deleteToken) {
51
+ return this.request("DELETE", `/api/v1/forms/${formToken}`, { headers: { "X-Delete-Token": deleteToken } });
52
+ }
53
+ async addRecipients(formToken, count) {
54
+ return this.request("POST", `/api/v1/forms/${formToken}/recipients`, { body: count !== undefined ? { count } : {} });
55
+ }
56
+ }
57
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/build/index.js ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { LetsClarifyClient } from "./client.js";
4
+ import { createServer } from "./server.js";
5
+ const apiKey = process.env.LETSCLARIFY_API_KEY;
6
+ if (!apiKey) {
7
+ console.error("Error: LETSCLARIFY_API_KEY environment variable is required.");
8
+ process.exit(1);
9
+ }
10
+ const baseUrl = process.env.LETSCLARIFY_BASE_URL || "https://letsclarify.ai";
11
+ const client = new LetsClarifyClient(apiKey, baseUrl);
12
+ const server = createServer(client);
13
+ const transport = new StdioServerTransport();
14
+ await server.connect(transport);
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;AAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;IACZ,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAC9E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,wBAAwB,CAAC;AAC7E,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACtD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAEpC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { LetsClarifyClient } from "./client.js";
3
+ export declare function createServer(client: LetsClarifyClient): McpServer;
4
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AA6FhD,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CA6BjE"}
@@ -0,0 +1,118 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { registerCreateForm } from "./tools/create-form.js";
3
+ import { registerGetFormSummary } from "./tools/get-form-summary.js";
4
+ import { registerGetFormResults } from "./tools/get-form-results.js";
5
+ import { registerDeleteForm } from "./tools/delete-form.js";
6
+ import { registerAddRecipients } from "./tools/add-recipients.js";
7
+ const SCHEMA_DSL_RESOURCE = `# LetsClarify Schema DSL Reference
8
+
9
+ ## Field Types
10
+
11
+ | Type | Description | Requires \`options\` |
12
+ |---|---|---|
13
+ | \`text\` | Single-line text input | No |
14
+ | \`textarea\` | Multi-line text input | No |
15
+ | \`checkbox\` | Single boolean checkbox | No |
16
+ | \`checkbox_group\` | Multiple checkboxes | Yes |
17
+ | \`radio\` | Radio button group | Yes |
18
+ | \`select\` | Dropdown select | Yes |
19
+ | \`file\` | File upload | No |
20
+
21
+ ## Field Object Structure
22
+
23
+ \`\`\`json
24
+ {
25
+ "id": "field_name", // unique, letters/digits/underscores
26
+ "type": "text", // one of the types above
27
+ "label": "Your Name", // human-readable label
28
+ "required": true, // optional, default false
29
+ "placeholder": "Enter…", // optional
30
+ "description": "Help text" // optional
31
+ }
32
+ \`\`\`
33
+
34
+ ## Options (required for radio, select, checkbox_group)
35
+
36
+ \`\`\`json
37
+ "options": [
38
+ { "value": "yes", "label": "Yes" },
39
+ { "value": "no", "label": "No" }
40
+ ]
41
+ \`\`\`
42
+
43
+ ## Validation Rules (optional)
44
+
45
+ - \`min_length\` / \`max_length\` — for text/textarea
46
+ - \`pattern\` — regex string for text/textarea
47
+ - \`min_items\` / \`max_items\` — for checkbox_group
48
+
49
+ \`\`\`json
50
+ "validation": { "min_length": 10, "max_length": 500 }
51
+ \`\`\`
52
+
53
+ ## File Config (optional, for file type only)
54
+
55
+ - \`accept\` — array of MIME types or extensions: \`["image/*", ".pdf"]\`
56
+ - \`max_size_mb\` — max file size in MB (1–10)
57
+ - \`max_files\` — max number of files (1–10)
58
+
59
+ \`\`\`json
60
+ "file": { "accept": [".pdf", "image/*"], "max_size_mb": 5, "max_files": 3 }
61
+ \`\`\`
62
+
63
+ ## Example Schema
64
+
65
+ \`\`\`json
66
+ [
67
+ {
68
+ "id": "decision",
69
+ "type": "radio",
70
+ "label": "Your decision",
71
+ "required": true,
72
+ "options": [
73
+ { "value": "approve", "label": "Approve" },
74
+ { "value": "reject", "label": "Reject" }
75
+ ]
76
+ },
77
+ {
78
+ "id": "notes",
79
+ "type": "textarea",
80
+ "label": "Additional notes",
81
+ "validation": { "max_length": 1000 }
82
+ },
83
+ {
84
+ "id": "attachment",
85
+ "type": "file",
86
+ "label": "Supporting document",
87
+ "file": { "accept": [".pdf", ".docx"], "max_size_mb": 10 }
88
+ }
89
+ ]
90
+ \`\`\`
91
+ `;
92
+ export function createServer(client) {
93
+ const server = new McpServer({
94
+ name: "letsclarify",
95
+ version: "1.0.0",
96
+ });
97
+ // Register tools
98
+ registerCreateForm(server, client);
99
+ registerGetFormSummary(server, client);
100
+ registerGetFormResults(server, client);
101
+ registerDeleteForm(server, client);
102
+ registerAddRecipients(server, client);
103
+ // Register schema DSL resource
104
+ server.resource("schema-dsl", "letsclarify://schema-dsl", {
105
+ description: "Schema DSL reference for LetsClarify form fields — types, validation, file config, and examples.",
106
+ mimeType: "text/markdown",
107
+ }, async () => ({
108
+ contents: [
109
+ {
110
+ uri: "letsclarify://schema-dsl",
111
+ mimeType: "text/markdown",
112
+ text: SCHEMA_DSL_RESOURCE,
113
+ },
114
+ ],
115
+ }));
116
+ return server;
117
+ }
118
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoF3B,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,MAAyB;IACpD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,iBAAiB;IACjB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEtC,+BAA+B;IAC/B,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,0BAA0B,EAAE;QACxD,WAAW,EACT,kGAAkG;QACpG,QAAQ,EAAE,eAAe;KAC1B,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QACd,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,0BAA0B;gBAC/B,QAAQ,EAAE,eAAe;gBACzB,IAAI,EAAE,mBAAmB;aAC1B;SACF;KACF,CAAC,CAAC,CAAC;IAEJ,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { LetsClarifyClient } from "../client.js";
3
+ export declare function registerAddRecipients(server: McpServer, client: LetsClarifyClient): void;
4
+ //# sourceMappingURL=add-recipients.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-recipients.d.ts","sourceRoot":"","sources":["../../src/tools/add-recipients.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,QAsBjF"}
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ export function registerAddRecipients(server, client) {
3
+ server.tool("add_recipients", "Add more recipient slots to an existing form. Returns new UUIDs. Build URLs using the base_url_template from create_form. Cannot be used on expired forms.", {
4
+ form_token: z.string().describe("The form token returned by create_form"),
5
+ count: z.number().int().min(1).max(1000).optional().describe("Number of new recipients to add (default: 1)"),
6
+ }, async (args) => {
7
+ try {
8
+ const result = await client.addRecipients(args.form_token, args.count);
9
+ return {
10
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
11
+ };
12
+ }
13
+ catch (error) {
14
+ return {
15
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
16
+ isError: true,
17
+ };
18
+ }
19
+ });
20
+ }
21
+ //# sourceMappingURL=add-recipients.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-recipients.js","sourceRoot":"","sources":["../../src/tools/add-recipients.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,MAAyB;IAChF,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,4JAA4J,EAC5J;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;QACzE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;KAC7G,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aAC5E,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;gBAC9G,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { LetsClarifyClient } from "../client.js";
3
+ export declare function registerCreateForm(server: McpServer, client: LetsClarifyClient): void;
4
+ //# sourceMappingURL=create-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-form.d.ts","sourceRoot":"","sources":["../../src/tools/create-form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAqCjD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,QAyD9E"}
@@ -0,0 +1,79 @@
1
+ import { z } from "zod";
2
+ const FieldValidation = z
3
+ .object({
4
+ min_length: z.number().int().nonnegative().optional(),
5
+ max_length: z.number().int().positive().optional(),
6
+ pattern: z.string().optional(),
7
+ min_items: z.number().int().nonnegative().optional(),
8
+ max_items: z.number().int().positive().optional(),
9
+ })
10
+ .optional();
11
+ const FileConfig = z
12
+ .object({
13
+ accept: z.array(z.string()).optional(),
14
+ max_size_mb: z.number().min(1).max(10).optional(),
15
+ max_files: z.number().int().min(1).max(10).optional(),
16
+ })
17
+ .optional();
18
+ const Option = z.object({
19
+ value: z.string(),
20
+ label: z.string(),
21
+ });
22
+ const SchemaField = z.object({
23
+ id: z.string().describe("Unique field identifier (letters, digits, underscores)"),
24
+ type: z.enum(["text", "textarea", "checkbox", "checkbox_group", "radio", "select", "file"]),
25
+ label: z.string().describe("Human-readable field label"),
26
+ required: z.boolean().optional(),
27
+ placeholder: z.string().optional(),
28
+ description: z.string().optional(),
29
+ options: z.array(Option).optional().describe("Required for radio, select, checkbox_group"),
30
+ file: FileConfig.describe("Optional config for file fields"),
31
+ validation: FieldValidation,
32
+ });
33
+ export function registerCreateForm(server, client) {
34
+ server.tool("create_form", `Create a LetsClarify form. Returns a form_token, delete_token, recipient UUIDs, and URL template.
35
+ Build shareable URLs by replacing {recipient_uuid} in base_url_template with each UUID.
36
+ Use the "letsclarify://schema-dsl" resource for field type reference.`, {
37
+ schema: z.array(SchemaField).min(1).max(50).describe("Form field definitions (1–50 fields)"),
38
+ title: z.string().optional().describe("Form title shown to recipients"),
39
+ context_markdown: z.string().optional().describe("Markdown context shown above the form"),
40
+ recipient_count: z.number().int().min(1).max(1000).optional().describe("Number of recipient slots (default: 1)"),
41
+ retention_days: z.number().int().min(1).max(365).optional().describe("Days until auto-deletion (default: 30)"),
42
+ webhook_url: z.string().optional().describe("HTTPS URL for submission webhooks"),
43
+ theme_color: z.string().optional().describe("Hex color for form branding, e.g. #1a2b3c"),
44
+ }, async (args) => {
45
+ try {
46
+ const result = await client.createForm({
47
+ schema: args.schema,
48
+ title: args.title,
49
+ context_markdown: args.context_markdown,
50
+ recipient_count: args.recipient_count,
51
+ retention_days: args.retention_days,
52
+ webhook_url: args.webhook_url,
53
+ theme_color: args.theme_color,
54
+ });
55
+ const urls = result.recipients.map((uuid) => result.base_url_template.replace("{recipient_uuid}", uuid));
56
+ return {
57
+ content: [
58
+ {
59
+ type: "text",
60
+ text: JSON.stringify({
61
+ form_token: result.form_token,
62
+ delete_token: result.delete_token,
63
+ recipient_urls: urls,
64
+ poll_url: result.poll_url,
65
+ summary_url: result.summary_url,
66
+ }, null, 2),
67
+ },
68
+ ],
69
+ };
70
+ }
71
+ catch (error) {
72
+ return {
73
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
74
+ isError: true,
75
+ };
76
+ }
77
+ });
78
+ }
79
+ //# sourceMappingURL=create-form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-form.js","sourceRoot":"","sources":["../../src/tools/create-form.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { LetsClarifyClient } from "../client.js";
3
+ export declare function registerDeleteForm(server: McpServer, client: LetsClarifyClient): void;
4
+ //# sourceMappingURL=delete-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-form.d.ts","sourceRoot":"","sources":["../../src/tools/delete-form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,QAsB9E"}
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ export function registerDeleteForm(server, client) {
3
+ server.tool("delete_form", "Permanently delete a form and all its data (recipients, submissions, files). This action is irreversible. Requires the delete_token from the create_form response.", {
4
+ form_token: z.string().describe("The form token returned by create_form"),
5
+ delete_token: z.string().describe("The delete token returned by create_form"),
6
+ }, async (args) => {
7
+ try {
8
+ const result = await client.deleteForm(args.form_token, args.delete_token);
9
+ return {
10
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
11
+ };
12
+ }
13
+ catch (error) {
14
+ return {
15
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
16
+ isError: true,
17
+ };
18
+ }
19
+ });
20
+ }
21
+ //# sourceMappingURL=delete-form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-form.js","sourceRoot":"","sources":["../../src/tools/delete-form.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,MAAyB;IAC7E,MAAM,CAAC,IAAI,CACT,aAAa,EACb,oKAAoK,EACpK;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;QACzE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;KAC9E,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YAC3E,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aAC5E,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;gBAC9G,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { LetsClarifyClient } from "../client.js";
3
+ export declare function registerGetFormResults(server: McpServer, client: LetsClarifyClient): void;
4
+ //# sourceMappingURL=get-form-results.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-form-results.d.ts","sourceRoot":"","sources":["../../src/tools/get-form-results.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,QAkClF"}
@@ -0,0 +1,32 @@
1
+ import { z } from "zod";
2
+ export function registerGetFormResults(server, client) {
3
+ server.tool("get_form_results", "Fetch paginated form results. Returns each recipient's status and submitted answers. Supports filtering by status and updated_since for efficient polling.", {
4
+ form_token: z.string().describe("The form token returned by create_form"),
5
+ limit: z.number().int().min(1).max(1000).optional().describe("Max results per page (default: 100)"),
6
+ cursor: z.string().optional().describe("Pagination cursor from a previous response"),
7
+ status: z.enum(["submitted", "pending"]).optional().describe("Filter by recipient status"),
8
+ updated_since: z.string().optional().describe("ISO8601 timestamp — only return results updated at or after this time"),
9
+ include_files: z.boolean().optional().describe("Include base64-encoded file contents (can be large)"),
10
+ }, async (args) => {
11
+ try {
12
+ const params = {
13
+ limit: args.limit?.toString(),
14
+ cursor: args.cursor,
15
+ status: args.status,
16
+ updated_since: args.updated_since,
17
+ include_files: args.include_files ? "1" : undefined,
18
+ };
19
+ const result = await client.getFormResults(args.form_token, params);
20
+ return {
21
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
22
+ };
23
+ }
24
+ catch (error) {
25
+ return {
26
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
27
+ isError: true,
28
+ };
29
+ }
30
+ });
31
+ }
32
+ //# sourceMappingURL=get-form-results.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-form-results.js","sourceRoot":"","sources":["../../src/tools/get-form-results.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,sBAAsB,CAAC,MAAiB,EAAE,MAAyB;IACjF,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,4JAA4J,EAC5J;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;QACzE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;QACnG,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;QACpF,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;QAC1F,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uEAAuE,CAAC;QACtH,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;KACtG,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAuC;gBACjD,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE;gBAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;aACpD,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YACpE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aAC5E,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;gBAC9G,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { LetsClarifyClient } from "../client.js";
3
+ export declare function registerGetFormSummary(server: McpServer, client: LetsClarifyClient): void;
4
+ //# sourceMappingURL=get-form-summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-form-summary.d.ts","sourceRoot":"","sources":["../../src/tools/get-form-summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,QAqBlF"}
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ export function registerGetFormSummary(server, client) {
3
+ server.tool("get_form_summary", "Get a quick overview of a form: how many recipients submitted vs. pending, and whether the form is expired.", {
4
+ form_token: z.string().describe("The form token returned by create_form"),
5
+ }, async (args) => {
6
+ try {
7
+ const result = await client.getFormSummary(args.form_token);
8
+ return {
9
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
10
+ };
11
+ }
12
+ catch (error) {
13
+ return {
14
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }],
15
+ isError: true,
16
+ };
17
+ }
18
+ });
19
+ }
20
+ //# sourceMappingURL=get-form-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-form-summary.js","sourceRoot":"","sources":["../../src/tools/get-form-summary.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,UAAU,sBAAsB,CAAC,MAAiB,EAAE,MAAyB;IACjF,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,6GAA6G,EAC7G;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;KAC1E,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC5D,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aAC5E,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;gBAC9G,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@heisee/letsclarify-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for LetsClarify — Human-in-the-Loop API for AI agents",
5
+ "license": "MIT",
6
+ "author": "heisee",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/heisee/LetsClarify",
10
+ "directory": "mcp-server"
11
+ },
12
+ "type": "module",
13
+ "main": "build/index.js",
14
+ "bin": {
15
+ "letsclarify-mcp": "build/index.js"
16
+ },
17
+ "files": [
18
+ "build"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "prepublishOnly": "npm run build"
23
+ },
24
+ "keywords": [
25
+ "mcp",
26
+ "model-context-protocol",
27
+ "letsclarify",
28
+ "human-in-the-loop",
29
+ "ai-agents",
30
+ "forms"
31
+ ],
32
+ "engines": {
33
+ "node": ">=18"
34
+ },
35
+ "dependencies": {
36
+ "@modelcontextprotocol/sdk": "^1.12.1",
37
+ "zod": "^3.25.1"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^22.15.21",
41
+ "typescript": "^5.8.3"
42
+ }
43
+ }