@extrovert.dev/mcp 0.1.0-pre.4 → 0.1.0-pre.5
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 +38 -13
- package/dist/bin.d.ts +5 -7
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +63 -54
- package/dist/bin.js.map +1 -1
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +459 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +20 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +41 -8
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/contract.d.ts +2 -2
- package/dist/contract.js +2 -2
- package/dist/credentials.d.ts +41 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +203 -0
- package/dist/credentials.js.map +1 -0
- package/dist/fixtures.d.ts.map +1 -1
- package/dist/fixtures.js +23 -2
- package/dist/fixtures.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +7 -4
- package/dist/server.js.map +1 -1
- package/dist/stdio.d.ts.map +1 -1
- package/dist/stdio.js +24 -2
- package/dist/stdio.js.map +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +28 -6
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +18 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +3 -1
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,YAAY,GAAG;IACnB,mEAAmE;IACnE,EAAE;IACF,eAAe;IACf,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AAC5F,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,YAAY,GAAG;IACnB,mEAAmE;IACnE,EAAE;IACF,eAAe;IACf,gHAAgH;IAChH,wGAAwG;IACxG,oGAAoG;IACpG,0GAA0G;IAC1G,6HAA6H;IAC7H,EAAE;IACF,gIAAgI;IAChI,8EAA8E;IAC9E,EAAE;IACF,wHAAwH;IACxH,0HAA0H;IAC1H,oCAAoC;CACrC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAOb,iEAAiE;AACjE,MAAM,UAAU,qBAAqB,CAAC,UAAwC,EAAE;IAK9E,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;IAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IAE7D,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,EAC9C;QACE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAC3B,YAAY,EAAE,YAAY;KAC3B,CACF,CAAC;IAEF,aAAa,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAE1C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC"}
|
package/dist/stdio.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAmC9C"}
|
package/dist/stdio.js
CHANGED
|
@@ -5,12 +5,34 @@
|
|
|
5
5
|
* to stderr only; stdout is reserved for the JSON-RPC stream.
|
|
6
6
|
*/
|
|
7
7
|
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
|
|
8
|
+
import { ExtrovertClient } from "./client.js";
|
|
9
|
+
import { loadConfig } from "./config.js";
|
|
10
|
+
import { createCredentialStore } from "./credentials.js";
|
|
8
11
|
import { createExtrovertServer } from "./server.js";
|
|
9
12
|
export async function runStdio() {
|
|
10
|
-
const
|
|
13
|
+
const credentialStore = createCredentialStore();
|
|
14
|
+
const stored = credentialStore.load();
|
|
15
|
+
const env = { ...process.env };
|
|
16
|
+
if (!(env.EXTROVERT_API_KEY ?? "").trim() && stored) {
|
|
17
|
+
env.EXTROVERT_API_KEY = stored.agent_key;
|
|
18
|
+
if (!(env.EXTROVERT_API_BASE_URL ?? "").trim()) {
|
|
19
|
+
env.EXTROVERT_API_BASE_URL = stored.api_base_url;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const config = loadConfig(env);
|
|
23
|
+
const client = new ExtrovertClient(config, {
|
|
24
|
+
onDurableAgentKey: config.mock
|
|
25
|
+
? undefined
|
|
26
|
+
: (agentKey, apiBaseUrl) => {
|
|
27
|
+
credentialStore.save(agentKey, apiBaseUrl);
|
|
28
|
+
return { location: credentialStore.paths.credential };
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
const { server } = createExtrovertServer({ config, client });
|
|
11
32
|
const transport = new StdioServerTransport();
|
|
12
33
|
await server.connect(transport);
|
|
13
|
-
const
|
|
34
|
+
const auth = config.apiKey ? "authenticated" : "ready for sign_up";
|
|
35
|
+
const mode = config.mock ? "offline fixtures" : `live API ${config.apiBaseUrl} · ${auth}`;
|
|
14
36
|
process.stderr.write(`extrovert-mcp: stdio transport ready — ${mode}\n`);
|
|
15
37
|
const shutdown = async () => {
|
|
16
38
|
await server.close().catch(() => { });
|
package/dist/stdio.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,qBAAqB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,eAAe,GAAG,qBAAqB,EAAE,CAAC;IAChD,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,CAAC;IACtC,MAAM,GAAG,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC/B,IAAI,CAAC,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;QACpD,GAAG,CAAC,iBAAiB,GAAG,MAAM,CAAC,SAAS,CAAC;QACzC,IAAI,CAAC,CAAC,GAAG,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/C,GAAG,CAAC,sBAAsB,GAAG,MAAM,CAAC,YAAY,CAAC;QACnD,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,EAAE;QACzC,iBAAiB,EAAE,MAAM,CAAC,IAAI;YAC5B,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE;gBACvB,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;gBAC3C,OAAO,EAAE,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;YACxD,CAAC;KACN,CAAC,CAAC;IACH,MAAM,EAAE,MAAM,EAAE,GAAG,qBAAqB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAE7D,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,mBAAmB,CAAC;IACnE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,UAAU,MAAM,IAAI,EAAE,CAAC;IAC1F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0CAA0C,IAAI,IAAI,CAAC,CAAC;IAEzE,MAAM,QAAQ,GAAG,KAAK,IAAmB,EAAE;QACzC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;AAC/C,CAAC"}
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,8BAA8B,CAAC;AAG/E,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA0CnD,UAAU,WAAW;IACnB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,eAAe,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,8BAA8B,CAAC;AAG/E,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA0CnD,UAAU,WAAW;IACnB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,eAAe,CAAC;CACzB;AAw4FD,wEAAwE;AACxE,eAAO,MAAM,UAAU,EAAE,MAAM,EAAiC,CAAC;AAEjE,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAIvE"}
|
package/dist/tools.js
CHANGED
|
@@ -436,6 +436,7 @@ const redeemEnrollment = defineTool({
|
|
|
436
436
|
agent_handle: args.agent_handle,
|
|
437
437
|
client_id: args.client_id,
|
|
438
438
|
});
|
|
439
|
+
const persistence = client.credentialPersistenceStatus();
|
|
439
440
|
const text = [
|
|
440
441
|
`Enrollment redeemed. Agent ${result.agent_id} is ready.`,
|
|
441
442
|
`agent_key (shown once): ${result.agent_key}`,
|
|
@@ -444,7 +445,7 @@ const redeemEnrollment = defineTool({
|
|
|
444
445
|
// whoami call — consistent with whoami's text.
|
|
445
446
|
`org: ${result.org_id || "(none)"} · project: ${result.project_id || "(none)"} (fixed — bound to this key)`,
|
|
446
447
|
`scopes: ${result.scopes.join(", ") || "(none)"}`,
|
|
447
|
-
|
|
448
|
+
credentialPersistenceMessage(persistence),
|
|
448
449
|
].join("\n");
|
|
449
450
|
return ok(text, result);
|
|
450
451
|
},
|
|
@@ -454,8 +455,8 @@ const signUp = defineTool({
|
|
|
454
455
|
title: "Sign up for a free account",
|
|
455
456
|
description: "Grab a free Extrovert account in one call (no enrollment token needed). Provisions a tenant and a first inbox, then " +
|
|
456
457
|
"emails a one-time verification code to your human_email. Returns a LIMITED (read-only) agent key that this " +
|
|
457
|
-
"MCP session keeps
|
|
458
|
-
"human_email rotates the key and resends the code.",
|
|
458
|
+
"MCP session keeps only through verify_signup; it expires with the code and is revoked after verification. " +
|
|
459
|
+
"Re-calling with the same human_email rotates the bootstrap key and resends the code.",
|
|
459
460
|
inputSchema: {
|
|
460
461
|
human_email: emailAddress.describe("Your email — receives the one-time verification code."),
|
|
461
462
|
username: z
|
|
@@ -473,7 +474,9 @@ const signUp = defineTool({
|
|
|
473
474
|
`inbox: ${res.address}`,
|
|
474
475
|
`agent_key (limited, shown once): ${res.agent_key}`,
|
|
475
476
|
`scopes: ${res.scopes.join(", ")}`,
|
|
476
|
-
`
|
|
477
|
+
`expires: ${res.otp_expires_at}`,
|
|
478
|
+
`This MCP session will use the limited key until verify_signup atomically exchanges it for the durable key. Do not store this bootstrap key for long-term use.`,
|
|
479
|
+
`After verification, verify_signup repeats the inbox and returns exact read_messages / get_message / wait_for_email calls so mailbox use can continue without raw HTTP.`,
|
|
477
480
|
].join("\n");
|
|
478
481
|
return ok(text, res);
|
|
479
482
|
},
|
|
@@ -481,22 +484,41 @@ const signUp = defineTool({
|
|
|
481
484
|
const verifySignup = defineTool({
|
|
482
485
|
name: "verify_signup",
|
|
483
486
|
title: "Verify signup code",
|
|
484
|
-
description: "Confirm the one-time code emailed by sign_up. On success
|
|
485
|
-
"
|
|
487
|
+
description: "Confirm the one-time code emailed by sign_up. On success the bootstrap key is revoked and you receive a NEW " +
|
|
488
|
+
"full-scope agent key (create/read/send/webhooks). This MCP session switches to it automatically. The packaged " +
|
|
489
|
+
"local stdio server also stores it in its permission-restricted credential file for future sessions.",
|
|
486
490
|
inputSchema: {
|
|
487
491
|
otp: z.string().min(4).max(12).describe("The verification code from your signup email."),
|
|
488
492
|
},
|
|
489
493
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
490
494
|
handler: async (args, { client }) => {
|
|
491
495
|
const res = await client.verify({ otp: args.otp });
|
|
496
|
+
const quick = res.mailbox_quickstart;
|
|
497
|
+
const persistence = client.credentialPersistenceStatus();
|
|
492
498
|
const text = [
|
|
493
499
|
`Verified. ${res.message}`,
|
|
494
500
|
`agent_key (full, shown once): ${res.agent_key}`,
|
|
495
501
|
`scopes: ${res.scopes.join(", ")}`,
|
|
502
|
+
credentialPersistenceMessage(persistence),
|
|
503
|
+
`mailbox ready: ${res.address}`,
|
|
504
|
+
`First call: ${quick.list_mail.tool} ${JSON.stringify(quick.list_mail.arguments)}`,
|
|
505
|
+
`Read one result: ${quick.read_message.tool} ${JSON.stringify(quick.read_message.arguments)}`,
|
|
506
|
+
`Wait for new mail: ${quick.wait_for_mail.tool} ${JSON.stringify(quick.wait_for_mail.arguments)}`,
|
|
507
|
+
`These tools return readable text plus structured message fields; do not download raw responses or invoke jq for ordinary mailbox work.`,
|
|
508
|
+
`For outbound mail, use send_email or reply_email through the review workflow; read get_inbox first to see the effective review policy.`,
|
|
496
509
|
].join("\n");
|
|
497
510
|
return ok(text, res);
|
|
498
511
|
},
|
|
499
512
|
});
|
|
513
|
+
function credentialPersistenceMessage(status) {
|
|
514
|
+
if (status.persisted) {
|
|
515
|
+
return `Credential saved for future local sessions${status.location ? ` at ${status.location}` : ""}.`;
|
|
516
|
+
}
|
|
517
|
+
if (status.attempted) {
|
|
518
|
+
return `Automatic credential storage failed${status.error ? `: ${status.error}` : ""}. Store the complete returned agent_key now; it is not retrievable again.`;
|
|
519
|
+
}
|
|
520
|
+
return "This host did not provide durable credential storage. Store the complete returned agent_key now; it is not retrievable again.";
|
|
521
|
+
}
|
|
500
522
|
const whoami = defineTool({
|
|
501
523
|
name: "whoami",
|
|
502
524
|
title: "Who am I",
|