idiolect-mcp 0.6.3 → 0.8.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 CHANGED
@@ -87,8 +87,12 @@ Hosted OAuth and API-key account mode advertise these six tools:
87
87
  - `view_writing_profile` reads your current Writing Profile, rules, or samples.
88
88
  - `manage_profile` creates or changes Writing Profiles and stated rules.
89
89
 
90
- If you have no Writing Profile, the service offers setup from your own writing or answers.
91
- You can skip setup and keep writing without a profile. After three completed pieces, one
90
+ If you have no Writing Profile, your first request can return `needs_profile_info`: questions
91
+ about how you write, each marked for the host or for you. Reply with `setup` (`choice` `profile`,
92
+ the same `writingJobVersionId`, and `firstRun` with each question, its answer and the returned
93
+ `round`). Idiolect AI then writes and starts your Writing Profile. `choice` `plain` writes now.
94
+ Where this is switched off, the service offers setup from your own writing or answers, and you
95
+ can skip setup and keep writing without a profile. After three completed pieces, one
92
96
  optional reminder may appear after the writing. Ignoring it does not repeat it; declining it
93
97
  stops future reminders. Follow the returned setup choices and reference. A reminder decline
94
98
  uses `setup.purpose` `reminder` and `setup.choice` `plain`; it never rewrites the completed piece.
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "idiolect-mcp",
3
- "version": "0.6.3",
3
+ "version": "0.8.0",
4
4
  "mcpName": "app.idiolect/idiolect-ai",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "idiolect-mcp": "server.mjs"
8
8
  },
9
- "description": "MCP server that gives any MCP-compatible AI (Claude, etc.) your Idiolect AI voice \u2014 make AI write as you. https://idiolect.app",
9
+ "description": "MCP server that gives any MCP-compatible AI (Claude, etc.) your Idiolect AI voice — make AI write as you. https://idiolect.app",
10
10
  "keywords": [
11
11
  "mcp",
12
12
  "model-context-protocol",
@@ -4,7 +4,7 @@
4
4
  {
5
5
  "name": "write",
6
6
  "title": "Write",
7
- "description": "Drafts an email, message, post, reply, doc, or report in the user's style. Use for new writing for or on behalf of the user, using their current Writing Profile when available. It writes from their request, facts, notes, or an outline, without inventing missing facts. The tool produces the draft. There is no need to draft it first. Works without a Writing Profile. Put the user's directions in `instructions`. It returns finished writing for direct presentation. When presenting the writing, preserve its wording.",
7
+ "description": "Drafts an email, message, post, reply, doc, or report in the user's style. Use for new writing for or on behalf of the user, using their current Writing Profile when available. It writes from their request, facts, notes, or an outline, without inventing missing facts. The tool produces the draft. There is no need to draft it first. For a person with no Writing Profile, the first result can ask questions about how they write before it writes. Put the user's directions in `instructions`. It returns finished writing for direct presentation. When presenting the writing, preserve its wording.",
8
8
  "inputSchema": {
9
9
  "type": "object",
10
10
  "properties": {
@@ -35,7 +35,7 @@
35
35
  "type": "string",
36
36
  "minLength": 1,
37
37
  "maxLength": 100,
38
- "description": "The language for the finished writing, such as French. When the user requests a language, set `language`. Otherwise, follow the request or source text language."
38
+ "description": "The language for the finished writing, as a BCP 47 language tag, such as `fr` or `pt-BR`. When the user requests a language, set `language`. Otherwise, follow the request or source text language."
39
39
  },
40
40
  "requestAuthor": {
41
41
  "type": "string",
@@ -232,6 +232,53 @@
232
232
  "alwaysUse": {
233
233
  "type": "boolean",
234
234
  "description": "True when the user asked to use this style for future writing."
235
+ },
236
+ "firstRun": {
237
+ "type": "object",
238
+ "properties": {
239
+ "round": {
240
+ "type": "integer",
241
+ "minimum": 0,
242
+ "maximum": 20
243
+ },
244
+ "answers": {
245
+ "type": "array",
246
+ "maxItems": 60,
247
+ "items": {
248
+ "type": "object",
249
+ "properties": {
250
+ "question": {
251
+ "type": "string",
252
+ "minLength": 1,
253
+ "maxLength": 4000
254
+ },
255
+ "answer": {
256
+ "type": "string",
257
+ "minLength": 1,
258
+ "maxLength": 20000
259
+ }
260
+ },
261
+ "required": [
262
+ "question",
263
+ "answer"
264
+ ],
265
+ "additionalProperties": false
266
+ },
267
+ "description": "Each question from the result, word for word, with its answer. An answer comes from what you know about the person or from the person."
268
+ },
269
+ "writing": {
270
+ "type": "array",
271
+ "maxItems": 12,
272
+ "items": {
273
+ "type": "string",
274
+ "minLength": 1,
275
+ "maxLength": 12000
276
+ },
277
+ "description": "Pieces that the person wrote themselves, word for word, that the person approved for this use. Not AI writing."
278
+ }
279
+ },
280
+ "additionalProperties": false,
281
+ "description": "Only when replying to a `needs_profile_info` result. Send each question with its answer. Send `unknown` as the answer when you do not know it. Send `round` as returned. Use `choice` `profile`."
235
282
  }
236
283
  },
237
284
  "required": [
@@ -239,6 +286,55 @@
239
286
  "choice"
240
287
  ],
241
288
  "additionalProperties": false
289
+ },
290
+ "aboutTheWriter": {
291
+ "type": "object",
292
+ "properties": {
293
+ "writesTo": {
294
+ "type": "string",
295
+ "minLength": 1,
296
+ "maxLength": 4000,
297
+ "description": "Who the person usually writes to."
298
+ },
299
+ "register": {
300
+ "type": "string",
301
+ "minLength": 1,
302
+ "maxLength": 4000,
303
+ "description": "How formal or casual their writing is."
304
+ },
305
+ "greetings": {
306
+ "type": "string",
307
+ "minLength": 1,
308
+ "maxLength": 4000,
309
+ "description": "How they usually greet people."
310
+ },
311
+ "signOff": {
312
+ "type": "string",
313
+ "minLength": 1,
314
+ "maxLength": 4000,
315
+ "description": "How they usually sign off, and with what name."
316
+ },
317
+ "habits": {
318
+ "type": "string",
319
+ "minLength": 1,
320
+ "maxLength": 4000,
321
+ "description": "Habits in their writing, such as length, layout or punctuation."
322
+ },
323
+ "wordsTheyUse": {
324
+ "type": "string",
325
+ "minLength": 1,
326
+ "maxLength": 4000,
327
+ "description": "Words or phrases they use a lot."
328
+ },
329
+ "wordsTheyAvoid": {
330
+ "type": "string",
331
+ "minLength": 1,
332
+ "maxLength": 4000,
333
+ "description": "Words or phrases they avoid."
334
+ }
335
+ },
336
+ "additionalProperties": false,
337
+ "description": "Optional: what you already know about how the person writes, from their own messages or what they told you. Leave out what you do not know. This is not a direction for this piece."
242
338
  }
243
339
  },
244
340
  "additionalProperties": false
@@ -272,7 +368,7 @@
272
368
  {
273
369
  "name": "rewrite",
274
370
  "title": "Rewrite",
275
- "description": "Rewrites text: 'make this sound like me', 'less AI', shorter, or clearer. Use for writing for or on behalf of the user, including drafts the host wrote for them. It rewrites in the user's style using their current Writing Profile when available. It covers an email, message, post, reply, or doc, from a grammar fix to a complete rewrite. Covers asks such as 'make this less AI-written' or 'make it less formal'. Changes include grammar, spelling, clarity, length, structure, tone, style, audience, or format. It can summarize, expand, simplify, paraphrase, or repurpose. Works without a Writing Profile. Unless the user asks to change them, it keeps supplied facts and protected wording. Put the user's change request in `instructions`. It returns finished writing for direct presentation. When presenting the writing, preserve its wording.",
371
+ "description": "Rewrites text: 'make this sound like me', 'less AI', shorter, or clearer. Use for writing for or on behalf of the user, including drafts the host wrote for them. It rewrites in the user's style using their current Writing Profile when available. It covers an email, message, post, reply, or doc, from a grammar fix to a complete rewrite. Covers asks such as 'make this less AI-written' or 'make it less formal'. Changes include grammar, spelling, clarity, length, structure, tone, style, audience, or format. It can summarize, expand, simplify, paraphrase, or repurpose. For a person with no Writing Profile, the first result can ask questions about how they write before it writes. Unless the user asks to change them, it keeps supplied facts and protected wording. Put the user's change request in `instructions`. It returns finished writing for direct presentation. When presenting the writing, preserve its wording.",
276
372
  "inputSchema": {
277
373
  "type": "object",
278
374
  "properties": {
@@ -303,7 +399,7 @@
303
399
  "type": "string",
304
400
  "minLength": 1,
305
401
  "maxLength": 100,
306
- "description": "The language for the finished writing, such as French. When the user requests a language, set `language`. Otherwise, follow the request or source text language."
402
+ "description": "The language for the finished writing, as a BCP 47 language tag, such as `fr` or `pt-BR`. When the user requests a language, set `language`. Otherwise, follow the request or source text language."
307
403
  },
308
404
  "sourceAuthor": {
309
405
  "type": "string",
@@ -500,6 +596,53 @@
500
596
  "alwaysUse": {
501
597
  "type": "boolean",
502
598
  "description": "True when the user asked to use this style for future writing."
599
+ },
600
+ "firstRun": {
601
+ "type": "object",
602
+ "properties": {
603
+ "round": {
604
+ "type": "integer",
605
+ "minimum": 0,
606
+ "maximum": 20
607
+ },
608
+ "answers": {
609
+ "type": "array",
610
+ "maxItems": 60,
611
+ "items": {
612
+ "type": "object",
613
+ "properties": {
614
+ "question": {
615
+ "type": "string",
616
+ "minLength": 1,
617
+ "maxLength": 4000
618
+ },
619
+ "answer": {
620
+ "type": "string",
621
+ "minLength": 1,
622
+ "maxLength": 20000
623
+ }
624
+ },
625
+ "required": [
626
+ "question",
627
+ "answer"
628
+ ],
629
+ "additionalProperties": false
630
+ },
631
+ "description": "Each question from the result, word for word, with its answer. An answer comes from what you know about the person or from the person."
632
+ },
633
+ "writing": {
634
+ "type": "array",
635
+ "maxItems": 12,
636
+ "items": {
637
+ "type": "string",
638
+ "minLength": 1,
639
+ "maxLength": 12000
640
+ },
641
+ "description": "Pieces that the person wrote themselves, word for word, that the person approved for this use. Not AI writing."
642
+ }
643
+ },
644
+ "additionalProperties": false,
645
+ "description": "Only when replying to a `needs_profile_info` result. Send each question with its answer. Send `unknown` as the answer when you do not know it. Send `round` as returned. Use `choice` `profile`."
503
646
  }
504
647
  },
505
648
  "required": [
@@ -507,6 +650,55 @@
507
650
  "choice"
508
651
  ],
509
652
  "additionalProperties": false
653
+ },
654
+ "aboutTheWriter": {
655
+ "type": "object",
656
+ "properties": {
657
+ "writesTo": {
658
+ "type": "string",
659
+ "minLength": 1,
660
+ "maxLength": 4000,
661
+ "description": "Who the person usually writes to."
662
+ },
663
+ "register": {
664
+ "type": "string",
665
+ "minLength": 1,
666
+ "maxLength": 4000,
667
+ "description": "How formal or casual their writing is."
668
+ },
669
+ "greetings": {
670
+ "type": "string",
671
+ "minLength": 1,
672
+ "maxLength": 4000,
673
+ "description": "How they usually greet people."
674
+ },
675
+ "signOff": {
676
+ "type": "string",
677
+ "minLength": 1,
678
+ "maxLength": 4000,
679
+ "description": "How they usually sign off, and with what name."
680
+ },
681
+ "habits": {
682
+ "type": "string",
683
+ "minLength": 1,
684
+ "maxLength": 4000,
685
+ "description": "Habits in their writing, such as length, layout or punctuation."
686
+ },
687
+ "wordsTheyUse": {
688
+ "type": "string",
689
+ "minLength": 1,
690
+ "maxLength": 4000,
691
+ "description": "Words or phrases they use a lot."
692
+ },
693
+ "wordsTheyAvoid": {
694
+ "type": "string",
695
+ "minLength": 1,
696
+ "maxLength": 4000,
697
+ "description": "Words or phrases they avoid."
698
+ }
699
+ },
700
+ "additionalProperties": false,
701
+ "description": "Optional: what you already know about how the person writes, from their own messages or what they told you. Leave out what you do not know. This is not a direction for this piece."
510
702
  }
511
703
  },
512
704
  "additionalProperties": false
@@ -570,7 +762,7 @@
570
762
  "type": "string",
571
763
  "minLength": 1,
572
764
  "maxLength": 100,
573
- "description": "Send only when this change asks for another language. The value is that language. Omit it to keep the language of the writing."
765
+ "description": "Send only when this change asks for another language. The value is a BCP 47 language tag, such as `fr`. Omit it to keep the language of the writing."
574
766
  },
575
767
  "situation": {
576
768
  "type": "object",
@@ -787,7 +979,7 @@
787
979
  {
788
980
  "name": "view_writing_profile",
789
981
  "title": "View writing profile",
790
- "description": "Shows the user's current Writing Profile and rules, and lists their Writing Profiles. To view another Writing Profile, set `profile` to its id or name. To list its writing samples, set `samples` true. Writing Profiles update continuously as the user writes, so read the current one here each time instead of keeping a saved copy.",
982
+ "description": "Shows the user's current Writing Profile and rules, and lists their Writing Profiles. To view another Writing Profile, set `profile` to its id or name. To list its writing samples, set `samples` true. A Writing Profile with habits shows how many habits each part holds and lists the habits that are not sure yet. To list the habits of one part, set `part`. To show one habit, set `habitId`. Writing Profiles update continuously as the user writes, so read the current one here each time instead of keeping a saved copy.",
791
983
  "inputSchema": {
792
984
  "type": "object",
793
985
  "properties": {
@@ -804,6 +996,24 @@
804
996
  "type": "string",
805
997
  "format": "uuid",
806
998
  "description": "With `samples`: the `nextCursor` from the previous page."
999
+ },
1000
+ "part": {
1001
+ "type": "string",
1002
+ "enum": [
1003
+ "core_voice",
1004
+ "convention",
1005
+ "never",
1006
+ "mark",
1007
+ "polish",
1008
+ "exemplar"
1009
+ ],
1010
+ "description": "To list every habit in one part of the Writing Profile, set the part: `core_voice` (how the user sounds), `convention` (formats and structure), `never` (what the user does not do), `mark` (words and marks they use), `polish` (spelling and punctuation) or `exemplar` (example pieces)."
1011
+ },
1012
+ "habitId": {
1013
+ "type": "string",
1014
+ "minLength": 1,
1015
+ "maxLength": 64,
1016
+ "description": "To show one habit, set the habit id from an earlier `view_writing_profile`."
807
1017
  }
808
1018
  },
809
1019
  "additionalProperties": false
@@ -836,7 +1046,7 @@
836
1046
  {
837
1047
  "name": "manage_profile",
838
1048
  "title": "Manage writing profile",
839
- "description": "Change the user's Writing Profiles and default writing template. Choose an `action`: `create_profile`, `add_samples`, `remove_sample`, `add_rule`, `remove_rule`, `rename_profile`, `set_current_profile`, or `set_default_template`. When the user shares writing they authored in this conversation, save it with `add_samples`. Without a Writing Profile, use `create_profile`. When the user states a lasting writing preference, save it with `add_rule`. Keep stated rules in the user's words and preserve their scope. Do not save inferred patterns as stated rules. Reuse that permission for the rest of this conversation without asking again. The user can delete a whole Writing Profile on the Idiolect AI website.",
1049
+ "description": "Change the user's Writing Profiles and default writing template, or answer a question Idiolect AI asked. Choose an `action`: `create_profile`, `add_samples`, `remove_sample`, `add_rule`, `remove_rule`, `rename_profile`, `set_current_profile`, `set_default_template`, `answer_question`, `confirm_habit`, `remove_habit`, or `restore_habit`. When the user shares writing they authored in this conversation, save it with `add_samples`. Without a Writing Profile, use `create_profile`. When the user states a lasting writing preference, save it with `add_rule`. Keep stated rules in the user's words and preserve their scope. Do not save inferred patterns as stated rules. When the user agrees that a habit from `view_writing_profile` is correct, use `confirm_habit`. When the user says a habit is wrong, use `remove_habit`. When the user says how they really write instead, use `add_rule` with `correctsHabitId`. Reuse that permission for the rest of this conversation without asking again. The user can delete a whole Writing Profile on the Idiolect AI website.",
840
1050
  "inputSchema": {
841
1051
  "type": "object",
842
1052
  "properties": {
@@ -850,9 +1060,13 @@
850
1060
  "remove_rule",
851
1061
  "rename_profile",
852
1062
  "set_current_profile",
853
- "set_default_template"
1063
+ "set_default_template",
1064
+ "answer_question",
1065
+ "confirm_habit",
1066
+ "remove_habit",
1067
+ "restore_habit"
854
1068
  ],
855
- "description": "Choose an `action`: `create_profile` builds from `evidence`; `add_samples` saves more writing; `remove_sample` deletes one sample. `add_rule` saves a stated preference; `remove_rule` deletes one rule. `rename_profile` changes its name; `set_current_profile` selects it for writing; `set_default_template` sets or clears a template."
1069
+ "description": "Choose an `action`: `create_profile` builds from `evidence`; `add_samples` saves more writing; `remove_sample` deletes one sample. `add_rule` saves a stated preference; `remove_rule` deletes one rule. `rename_profile` changes its name; `set_current_profile` selects it for writing; `set_default_template` sets or clears a template. `answer_question` records an answer to a question Idiolect AI asked. `confirm_habit` marks a habit as correct; `remove_habit` stops writing from using it; `restore_habit` undoes a removal."
856
1070
  },
857
1071
  "profile": {
858
1072
  "type": "string",
@@ -1002,6 +1216,18 @@
1002
1216
  "format": "uuid",
1003
1217
  "description": "For `remove_rule`: the rule id from `view_writing_profile`."
1004
1218
  },
1219
+ "habitId": {
1220
+ "type": "string",
1221
+ "minLength": 1,
1222
+ "maxLength": 64,
1223
+ "description": "For `confirm_habit`, `remove_habit` and `restore_habit`: the habit id from `view_writing_profile`. Set `profile` for a Writing Profile that is not current."
1224
+ },
1225
+ "correctsHabitId": {
1226
+ "type": "string",
1227
+ "minLength": 1,
1228
+ "maxLength": 64,
1229
+ "description": "For `add_rule`: the id of the habit this rule corrects. The rule is saved and the habit is removed. Set `profile` to the Writing Profile that holds the habit; omit it for the current one."
1230
+ },
1005
1231
  "sampleId": {
1006
1232
  "type": "string",
1007
1233
  "format": "uuid",
@@ -1020,6 +1246,42 @@
1020
1246
  "type": "boolean",
1021
1247
  "const": true,
1022
1248
  "description": "For `set_default_template`: clear the default template. Send `clear` or `templateId`, but not both."
1249
+ },
1250
+ "questionId": {
1251
+ "type": "string",
1252
+ "format": "uuid",
1253
+ "description": "For `answer_question`: the `questionId` Idiolect AI gave with the question."
1254
+ },
1255
+ "answeredBy": {
1256
+ "type": "string",
1257
+ "enum": [
1258
+ "user",
1259
+ "host"
1260
+ ],
1261
+ "description": "For `answer_question`: `user` when the user chose, `host` when you answer from this conversation."
1262
+ },
1263
+ "option": {
1264
+ "type": "string",
1265
+ "minLength": 1,
1266
+ "maxLength": 40,
1267
+ "description": "For `answer_question`: the chosen option id. A host that does not know sends `unknown`. A user who skips the question sends `decline`. For the user, omit it to show them a form where the client supports one."
1268
+ },
1269
+ "text": {
1270
+ "type": "string",
1271
+ "minLength": 1,
1272
+ "maxLength": 2000,
1273
+ "description": "For `answer_question`: optional detail the user or host gave with the answer."
1274
+ },
1275
+ "sources": {
1276
+ "type": "array",
1277
+ "minItems": 1,
1278
+ "maxItems": 20,
1279
+ "items": {
1280
+ "type": "string",
1281
+ "minLength": 1,
1282
+ "maxLength": 500
1283
+ },
1284
+ "description": "For `answer_question` with `answeredBy` `host`: where in this conversation you found the answer. Required unless `option` is `unknown`."
1023
1285
  }
1024
1286
  },
1025
1287
  "required": [