@formstr/mcp 0.1.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 +120 -0
- package/dist/index.js +44444 -0
- package/dist/index.js.map +1 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# @formstr/mcp
|
|
2
|
+
|
|
3
|
+
A standalone [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that
|
|
4
|
+
exposes the **Formstr** super-app (forms, calendar, pages, drive, polls) to any MCP host —
|
|
5
|
+
Claude Code/Desktop, Cursor, and others. It builds on `@formstr/core` and the super-app's
|
|
6
|
+
service layer and talks to Nostr relays directly. Transport: **stdio**.
|
|
7
|
+
|
|
8
|
+
v2 adds a **secure login flow** (your key lives in the OS keychain or a remote NIP-46
|
|
9
|
+
signer — never in your host config or the chat) and the **complete forms tool surface**.
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# 1. Sign in once (opens a browser; key is stored in your OS keychain)
|
|
15
|
+
npx -y @formstr/mcp login
|
|
16
|
+
|
|
17
|
+
# 2. Point your MCP host at the server (see "Host configuration")
|
|
18
|
+
# No key in the config — it's read from the keychain at startup.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Subcommands: `formstr-mcp login` · `formstr-mcp whoami` · `formstr-mcp logout` ·
|
|
22
|
+
`formstr-mcp` (run the stdio server, the default).
|
|
23
|
+
|
|
24
|
+
## Sign-in
|
|
25
|
+
|
|
26
|
+
`formstr-mcp login` starts a one-shot localhost page (it also prints the URL for
|
|
27
|
+
headless/SSH use) offering the same choices as the super-app:
|
|
28
|
+
|
|
29
|
+
| Method | What happens |
|
|
30
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
31
|
+
| **Paste nsec** | Validated locally; the key is stored in your OS keychain. |
|
|
32
|
+
| **Create guest** | A fresh Nostr key is generated and stored in your keychain. |
|
|
33
|
+
| **Connect signer (NIP-46)** | Scan/paste a `nostrconnect://` URI in Amber / nsec.app / nsecbunker. Your key stays there; the MCP keeps only a session token. |
|
|
34
|
+
|
|
35
|
+
**Where the key lives:** the OS keychain (macOS Keychain / Windows Credential Manager /
|
|
36
|
+
Linux Secret Service via `@napi-rs/keyring`). On hosts without a keychain (e.g. headless
|
|
37
|
+
Linux), set `FORMSTR_MCP_PASSPHRASE` to use an AES-256-GCM encrypted file at
|
|
38
|
+
`~/.config/formstr-mcp/credentials.enc` (mode `0600`). Multiple identities are supported;
|
|
39
|
+
select one with `--account <pubkey>`.
|
|
40
|
+
|
|
41
|
+
**The agent never sees your key.** No tool returns key material, and login happens
|
|
42
|
+
out-of-band, so secrets never enter the chat transcript.
|
|
43
|
+
|
|
44
|
+
## Host configuration
|
|
45
|
+
|
|
46
|
+
After `login`, no key belongs in the config:
|
|
47
|
+
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"mcpServers": {
|
|
51
|
+
"formstr": {
|
|
52
|
+
"command": "npx",
|
|
53
|
+
"args": ["-y", "@formstr/mcp"]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Add `"--allow-writes"` to `args` to enable the gated (destructive/outward) tools, and
|
|
60
|
+
`"--relays", "wss://a,wss://b"` to override relays.
|
|
61
|
+
|
|
62
|
+
## Headless / CI
|
|
63
|
+
|
|
64
|
+
For unattended use where no keychain or browser is available, provide a plaintext key.
|
|
65
|
+
The server **prints a prominent security warning** when you do this — prefer `login`.
|
|
66
|
+
|
|
67
|
+
| Variable | Meaning |
|
|
68
|
+
| --------------------------- | --------------------------------------------------- |
|
|
69
|
+
| `FORMSTR_NSEC` | signing key (plaintext) |
|
|
70
|
+
| `FORMSTR_RELAYS` | comma-separated relay override (optional) |
|
|
71
|
+
| `FORMSTR_ALLOW_WRITES=true` | enable gated tools (optional) |
|
|
72
|
+
| `FORMSTR_MCP_PASSPHRASE` | passphrase for the encrypted-file keystore fallback |
|
|
73
|
+
|
|
74
|
+
CLI flags: `--nsec <nsec>`, `--relays <wss://a,wss://b>`, `--allow-writes`, `--account <pubkey>`.
|
|
75
|
+
Precedence: plaintext flag/env/`config.json` → keychain → "run `formstr-mcp login`".
|
|
76
|
+
|
|
77
|
+
## Forms tools
|
|
78
|
+
|
|
79
|
+
The forms module is fully implemented — the MCP can create **every** field type the
|
|
80
|
+
service supports (more than the super-app builder UI currently exposes).
|
|
81
|
+
|
|
82
|
+
**Read (always on)**
|
|
83
|
+
|
|
84
|
+
- `list_forms` — your forms with ids, encryption status, and naddr coordinates.
|
|
85
|
+
- `get_form` — a form's fields, settings, and encryption status (pass `viewKey` for encrypted forms).
|
|
86
|
+
- `fetch_form_responses` — submissions with responder npub and per-field answers.
|
|
87
|
+
|
|
88
|
+
**Create / import (always on)**
|
|
89
|
+
|
|
90
|
+
- `create_form` — name, description, fields (short/paragraph/choice/dropdown/number/date/
|
|
91
|
+
time/grid/file/signature/section), per-field `validation`, title/cover images, thank-you
|
|
92
|
+
text, `publicForm`, `encrypted`, `allowedResponders`, `collaborators`, `notifyNpubs`.
|
|
93
|
+
- `import_form_from_naddr` — add a form by `naddr1…` / `pubkey:formId` to your forms list.
|
|
94
|
+
|
|
95
|
+
**Gated (require `--allow-writes` + `confirm: true`)**
|
|
96
|
+
|
|
97
|
+
- `update_form` — republish a form's name/fields/description.
|
|
98
|
+
- `share_form` — gift-wrap (NIP-59) an encrypted form's view key to collaborators.
|
|
99
|
+
- `delete_form` — publish a NIP-09 deletion.
|
|
100
|
+
- `submit_form_response` — submit a response on your identity.
|
|
101
|
+
|
|
102
|
+
Other modules (calendar, pages, polls, drive) expose the v1 read/create tools and gated
|
|
103
|
+
actions; see the source under `src/tools/`.
|
|
104
|
+
|
|
105
|
+
## Safety model
|
|
106
|
+
|
|
107
|
+
Destructive / outward tools are **not registered** unless `--allow-writes` (or
|
|
108
|
+
`FORMSTR_ALLOW_WRITES=true`) is set, AND each such call additionally requires
|
|
109
|
+
`"confirm": true`. Without `confirm`, the tool returns a structured "confirmation
|
|
110
|
+
required" message naming the irreversible effect instead of executing. `share_form`
|
|
111
|
+
distributes only the view key (read access) — never the signing key. Logging goes to
|
|
112
|
+
stderr (stdout is the MCP transport).
|
|
113
|
+
|
|
114
|
+
## Tests
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
pnpm --filter @formstr/mcp test # unit + stdio smoke test
|
|
118
|
+
pnpm --filter @formstr/mcp typecheck
|
|
119
|
+
pnpm --filter @formstr/mcp build # single-file CJS bundle (keychain dep stays external)
|
|
120
|
+
```
|