@almightygpt/core 0.8.1 → 0.9.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/dist/index.d.ts CHANGED
@@ -12,7 +12,8 @@
12
12
  * - review/ ✅ task #11 diff review pipeline (with #12/#13/#14 wiring)
13
13
  * - budget/ ✅ task #14 BudgetTracker + BudgetExceededError
14
14
  */
15
- export declare const VERSION = "0.8.1";
15
+ export declare const VERSION = "0.9.0";
16
+ export { startMcpServer } from "./mcp/server.js";
16
17
  export { checkGitStatus, assertSafeToWrite, GitStatusDirtyError, type GitStatusCheck, } from "./git/status.js";
17
18
  export { installTemplate, hasExistingConfig, type InstallOptions, type InstallResult, } from "./templates/install.js";
18
19
  export { loadConfig, ConfigError } from "./config/load.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,cAAc,GACpB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,KAAK,MAAM,EACX,KAAK,WAAW,GACjB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,aAAa,EACb,aAAa,EACb,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,YAAY,EACZ,aAAa,EACb,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,aAAa,EACb,cAAc,EACd,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,4BAA4B,EAC5B,KAAK,sBAAsB,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,aAAa,EACb,aAAa,EACb,KAAK,cAAc,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,aAAa,GACnB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,KAAK,cAAc,GACpB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,KAAK,MAAM,EACX,KAAK,WAAW,GACjB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,aAAa,EACb,aAAa,EACb,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,gBAAgB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,YAAY,EACZ,aAAa,EACb,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,QAAQ,EACR,WAAW,EACX,aAAa,EACb,cAAc,EACd,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,4BAA4B,EAC5B,KAAK,sBAAsB,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,aAAa,EACb,aAAa,EACb,KAAK,cAAc,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,aAAa,GACnB,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -12,7 +12,9 @@
12
12
  * - review/ ✅ task #11 diff review pipeline (with #12/#13/#14 wiring)
13
13
  * - budget/ ✅ task #14 BudgetTracker + BudgetExceededError
14
14
  */
15
- export const VERSION = "0.8.1";
15
+ export const VERSION = "0.9.0";
16
+ // MCP server (v0.9.0+) — exposes AlmightyGPT's review surface as MCP tools.
17
+ export { startMcpServer } from "./mcp/server.js";
16
18
  // Git safety primitives
17
19
  export { checkGitStatus, assertSafeToWrite, GitStatusDirtyError, } from "./git/status.js";
18
20
  // Template installer
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,wBAAwB;AACxB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,mBAAmB,GAEpB,MAAM,iBAAiB,CAAC;AAEzB,qBAAqB;AACrB,OAAO,EACL,eAAe,EACf,iBAAiB,GAGlB,MAAM,wBAAwB,CAAC;AAEhC,SAAS;AACT,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,GAGhB,MAAM,oBAAoB,CAAC;AAE5B,WAAW;AACX,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,aAAa,EACb,aAAa,GAQd,MAAM,qBAAqB,CAAC;AAE7B,sBAAsB;AACtB,OAAO,EAAE,aAAa,EAA6C,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GAGrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO;AACP,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAElB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,aAAa,EACb,cAAc,GAIf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,GAGf,MAAM,kBAAkB,CAAC;AAE1B,kBAAkB;AAClB,OAAO,EACL,aAAa,GAGd,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,uBAAuB,GAGxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,cAAc,EAAqC,MAAM,kBAAkB,CAAC;AACrF,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,4BAA4B,GAE7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,aAAa,EACb,mBAAmB,GAEpB,MAAM,oBAAoB,CAAC;AAO5B,2DAA2D;AAC3D,OAAO,EACL,aAAa,EACb,aAAa,GAEd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,WAAW,EACX,mBAAmB,GAEpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAyB,MAAM,qBAAqB,CAAC;AACzE,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,GAIlB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,4EAA4E;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,wBAAwB;AACxB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,mBAAmB,GAEpB,MAAM,iBAAiB,CAAC;AAEzB,qBAAqB;AACrB,OAAO,EACL,eAAe,EACf,iBAAiB,GAGlB,MAAM,wBAAwB,CAAC;AAEhC,SAAS;AACT,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,GAGhB,MAAM,oBAAoB,CAAC;AAE5B,WAAW;AACX,OAAO,EACL,YAAY,EACZ,WAAW,EACX,aAAa,EACb,aAAa,EACb,aAAa,GAQd,MAAM,qBAAqB,CAAC;AAE7B,sBAAsB;AACtB,OAAO,EAAE,aAAa,EAA6C,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GAGrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO;AACP,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAElB,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,aAAa,EACb,cAAc,GAIf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,GAGf,MAAM,kBAAkB,CAAC;AAE1B,kBAAkB;AAClB,OAAO,EACL,aAAa,GAGd,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,uBAAuB,GAGxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,cAAc,EAAqC,MAAM,kBAAkB,CAAC;AACrF,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,4BAA4B,GAE7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,aAAa,EACb,mBAAmB,GAEpB,MAAM,oBAAoB,CAAC;AAO5B,2DAA2D;AAC3D,OAAO,EACL,aAAa,EACb,aAAa,GAEd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,WAAW,EACX,mBAAmB,GAEpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAyB,MAAM,qBAAqB,CAAC;AACzE,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,GAIlB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * AlmightyGPT MCP server.
3
+ *
4
+ * Exposes the AlmightyGPT CLI's review/precommit/auth/runs surface as
5
+ * Model Context Protocol tools, so MCP-aware clients (Claude Desktop,
6
+ * Cursor, Continue, etc.) can invoke them directly.
7
+ *
8
+ * Transport: stdio (the default for local MCP servers). Spawned from
9
+ * the user's MCP client config — typically something like:
10
+ *
11
+ * {
12
+ * "mcpServers": {
13
+ * "almightygpt": {
14
+ * "command": "almightygpt",
15
+ * "args": ["mcp", "serve"]
16
+ * }
17
+ * }
18
+ * }
19
+ *
20
+ * Tool surface (v0.9.0):
21
+ * - review_diff: run a Worker/Reviewer or Reviewer-only review on a diff
22
+ * - precommit: quick last-mile review of uncommitted changes
23
+ * - auth_status: see which providers are configured
24
+ * - runs_list: list recent runs
25
+ * - runs_latest: show the most recent run
26
+ *
27
+ * Each tool is a thin wrapper around the existing core functions —
28
+ * no orchestration logic lives here. The CLI and MCP server are
29
+ * peer transports for the same underlying capabilities.
30
+ */
31
+ interface ServeOptions {
32
+ /** Override the cwd the MCP server treats as the repo root. */
33
+ cwd?: string;
34
+ }
35
+ /**
36
+ * Start the AlmightyGPT MCP server on stdio. Blocks for the lifetime
37
+ * of the process (returns the connect() promise — caller should await
38
+ * it inside the CLI command handler).
39
+ */
40
+ export declare function startMcpServer(options?: ServeOptions): Promise<void>;
41
+ export {};
42
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAkBH,UAAU,YAAY;IACpB,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+Q9E"}
@@ -0,0 +1,317 @@
1
+ /**
2
+ * AlmightyGPT MCP server.
3
+ *
4
+ * Exposes the AlmightyGPT CLI's review/precommit/auth/runs surface as
5
+ * Model Context Protocol tools, so MCP-aware clients (Claude Desktop,
6
+ * Cursor, Continue, etc.) can invoke them directly.
7
+ *
8
+ * Transport: stdio (the default for local MCP servers). Spawned from
9
+ * the user's MCP client config — typically something like:
10
+ *
11
+ * {
12
+ * "mcpServers": {
13
+ * "almightygpt": {
14
+ * "command": "almightygpt",
15
+ * "args": ["mcp", "serve"]
16
+ * }
17
+ * }
18
+ * }
19
+ *
20
+ * Tool surface (v0.9.0):
21
+ * - review_diff: run a Worker/Reviewer or Reviewer-only review on a diff
22
+ * - precommit: quick last-mile review of uncommitted changes
23
+ * - auth_status: see which providers are configured
24
+ * - runs_list: list recent runs
25
+ * - runs_latest: show the most recent run
26
+ *
27
+ * Each tool is a thin wrapper around the existing core functions —
28
+ * no orchestration logic lives here. The CLI and MCP server are
29
+ * peer transports for the same underlying capabilities.
30
+ */
31
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
32
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
33
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
34
+ import { runDiffReview } from "../review/run-diff-review.js";
35
+ import { runWorkerReviewerReview } from "../review/run-worker-reviewer.js";
36
+ import { listRuns, findLatestRun } from "../runs/list.js";
37
+ import { resolveApiKey } from "../auth/resolver.js";
38
+ import { PROVIDER_ENV_VARS } from "../auth/types.js";
39
+ import { loadConfig } from "../config/load.js";
40
+ const SERVER_NAME = "almightygpt";
41
+ /**
42
+ * Start the AlmightyGPT MCP server on stdio. Blocks for the lifetime
43
+ * of the process (returns the connect() promise — caller should await
44
+ * it inside the CLI command handler).
45
+ */
46
+ export async function startMcpServer(options = {}) {
47
+ const repoRoot = options.cwd ?? process.cwd();
48
+ const server = new Server({
49
+ name: SERVER_NAME,
50
+ version: "0.9.0",
51
+ }, {
52
+ capabilities: {
53
+ tools: {},
54
+ },
55
+ });
56
+ // Tool list — what clients see when they introspect the server.
57
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
58
+ tools: [
59
+ {
60
+ name: "review_diff",
61
+ description: "Run a cross-AI review on a git diff. Use `worker` to enable the " +
62
+ "Worker/Reviewer two-role flow, or omit for reviewer-only. Returns " +
63
+ "the review markdown plus cost/latency metrics.",
64
+ inputSchema: {
65
+ type: "object",
66
+ properties: {
67
+ topic: {
68
+ type: "string",
69
+ description: "Topic slug for the review file path (e.g. 'auth-refactor').",
70
+ },
71
+ reviewer: {
72
+ type: "string",
73
+ description: "Reviewer agent name. Falls back to config.defaults.reviewer.",
74
+ },
75
+ worker: {
76
+ type: "string",
77
+ description: "Worker agent name. If set, runs the two-role flow.",
78
+ },
79
+ range: {
80
+ type: "string",
81
+ description: "Git range like 'HEAD~3..HEAD'. Omit for uncommitted.",
82
+ },
83
+ force: {
84
+ type: "boolean",
85
+ description: "Overwrite existing review file. Default false.",
86
+ },
87
+ },
88
+ required: ["topic"],
89
+ },
90
+ },
91
+ {
92
+ name: "precommit",
93
+ description: "Quick last-mile review of uncommitted changes using the configured " +
94
+ "quick reviewer (Gemini Flash by default). Cheap (~$0.003) and fast. " +
95
+ "Returns review markdown + shallow-flag for CI gating.",
96
+ inputSchema: {
97
+ type: "object",
98
+ properties: {
99
+ topic: {
100
+ type: "string",
101
+ description: "Topic slug. Defaults to `precommit-<unix-timestamp>` if omitted.",
102
+ },
103
+ reviewer: {
104
+ type: "string",
105
+ description: "Override the quick reviewer. Defaults to config.defaults.quickReviewer.",
106
+ },
107
+ range: {
108
+ type: "string",
109
+ description: "Git range. Omit for uncommitted changes.",
110
+ },
111
+ },
112
+ },
113
+ },
114
+ {
115
+ name: "auth_status",
116
+ description: "Report which providers (OpenAI, Anthropic, Google) have API keys " +
117
+ "configured, and from where (env var vs keychain vs missing).",
118
+ inputSchema: {
119
+ type: "object",
120
+ properties: {},
121
+ },
122
+ },
123
+ {
124
+ name: "runs_list",
125
+ description: "List recent AlmightyGPT runs with cost, status, and timestamps.",
126
+ inputSchema: {
127
+ type: "object",
128
+ properties: {
129
+ limit: {
130
+ type: "number",
131
+ description: "Max runs to return. Default 10.",
132
+ },
133
+ },
134
+ },
135
+ },
136
+ {
137
+ name: "runs_latest",
138
+ description: "Show the most recent run (path to review file + metrics).",
139
+ inputSchema: {
140
+ type: "object",
141
+ properties: {},
142
+ },
143
+ },
144
+ ],
145
+ }));
146
+ // Tool dispatcher — routes to the right core function.
147
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
148
+ const { name, arguments: args = {} } = request.params;
149
+ const a = args;
150
+ try {
151
+ switch (name) {
152
+ case "review_diff": {
153
+ const topic = String(a["topic"]);
154
+ if (!topic)
155
+ throw new Error("`topic` is required");
156
+ const useWorker = typeof a["worker"] === "string";
157
+ if (useWorker) {
158
+ const opts = {
159
+ repoRoot,
160
+ topic,
161
+ force: a["force"] === true,
162
+ };
163
+ if (typeof a["range"] === "string")
164
+ opts.range = a["range"];
165
+ if (typeof a["worker"] === "string")
166
+ opts.worker = a["worker"];
167
+ if (typeof a["reviewer"] === "string")
168
+ opts.reviewer = a["reviewer"];
169
+ const result = await runWorkerReviewerReview(opts);
170
+ return formatReviewResult({
171
+ reviewPath: result.reviewPath,
172
+ tokensIn: result.totals.tokensIn,
173
+ tokensOut: result.totals.tokensOut,
174
+ costUsd: result.totals.costUsd,
175
+ latencyMs: result.totals.latencyMs,
176
+ filesReviewed: result.filesReviewed.length,
177
+ runFolder: result.runFolder,
178
+ worker: result.worker.name,
179
+ reviewer: result.reviewer.name,
180
+ });
181
+ }
182
+ const opts = {
183
+ repoRoot,
184
+ topic,
185
+ force: a["force"] === true,
186
+ };
187
+ if (typeof a["range"] === "string")
188
+ opts.range = a["range"];
189
+ if (typeof a["reviewer"] === "string")
190
+ opts.reviewer = a["reviewer"];
191
+ const result = await runDiffReview(opts);
192
+ return formatReviewResult({
193
+ reviewPath: result.reviewPath,
194
+ tokensIn: result.tokensIn,
195
+ tokensOut: result.tokensOut,
196
+ costUsd: result.costUsd,
197
+ latencyMs: result.latencyMs,
198
+ filesReviewed: result.filesReviewed.length,
199
+ runFolder: result.runFolder,
200
+ reviewer: result.reviewer,
201
+ shallowWarning: result.shallowWarning,
202
+ });
203
+ }
204
+ case "precommit": {
205
+ const config = await loadConfig(repoRoot);
206
+ const reviewer = (typeof a["reviewer"] === "string" && a["reviewer"]) ||
207
+ config.defaults.quickReviewer ||
208
+ config.defaults.reviewer;
209
+ if (!reviewer) {
210
+ throw new Error("No quick reviewer configured. Set defaults.quickReviewer in " +
211
+ ".almightygpt/config.yaml or pass `reviewer`.");
212
+ }
213
+ const topic = (typeof a["topic"] === "string" && a["topic"]) ||
214
+ `precommit-${Math.floor(Date.now() / 1000)}`;
215
+ const opts = {
216
+ repoRoot,
217
+ topic,
218
+ reviewer,
219
+ force: true,
220
+ };
221
+ if (typeof a["range"] === "string")
222
+ opts.range = a["range"];
223
+ const precommitDir = config.precommitDir;
224
+ if (precommitDir)
225
+ opts.reviewsDirOverride = precommitDir;
226
+ const result = await runDiffReview(opts);
227
+ return formatReviewResult({
228
+ reviewPath: result.reviewPath,
229
+ tokensIn: result.tokensIn,
230
+ tokensOut: result.tokensOut,
231
+ costUsd: result.costUsd,
232
+ latencyMs: result.latencyMs,
233
+ filesReviewed: result.filesReviewed.length,
234
+ runFolder: result.runFolder,
235
+ reviewer,
236
+ shallowWarning: result.shallowWarning,
237
+ });
238
+ }
239
+ case "auth_status": {
240
+ const providers = ["openai", "anthropic", "google"];
241
+ const rows = await Promise.all(providers.map(async (p) => {
242
+ const r = await resolveApiKey(p);
243
+ return {
244
+ provider: p,
245
+ source: r.source,
246
+ envVar: r.envVar ?? PROVIDER_ENV_VARS[p][0],
247
+ configured: r.source !== "missing",
248
+ };
249
+ }));
250
+ return {
251
+ content: [
252
+ {
253
+ type: "text",
254
+ text: JSON.stringify({ providers: rows }, null, 2),
255
+ },
256
+ ],
257
+ };
258
+ }
259
+ case "runs_list": {
260
+ const config = await loadConfig(repoRoot);
261
+ const limit = typeof a["limit"] === "number" ? a["limit"] : 10;
262
+ const result = await listRuns({
263
+ repoRoot,
264
+ runsDir: config.runsDir,
265
+ limit,
266
+ });
267
+ return {
268
+ content: [
269
+ { type: "text", text: JSON.stringify(result, null, 2) },
270
+ ],
271
+ };
272
+ }
273
+ case "runs_latest": {
274
+ const config = await loadConfig(repoRoot);
275
+ const result = await findLatestRun(repoRoot, config.runsDir);
276
+ return {
277
+ content: [
278
+ { type: "text", text: JSON.stringify(result ?? null, null, 2) },
279
+ ],
280
+ };
281
+ }
282
+ default:
283
+ throw new Error(`Unknown tool: ${name}`);
284
+ }
285
+ }
286
+ catch (err) {
287
+ const message = err instanceof Error ? err.message : String(err);
288
+ return {
289
+ isError: true,
290
+ content: [{ type: "text", text: `Error: ${message}` }],
291
+ };
292
+ }
293
+ });
294
+ const transport = new StdioServerTransport();
295
+ await server.connect(transport);
296
+ }
297
+ /** Compact summary of a review result for MCP clients. */
298
+ function formatReviewResult(r) {
299
+ const summary = {
300
+ reviewPath: r.reviewPath,
301
+ reviewer: r.reviewer,
302
+ ...(r.worker ? { worker: r.worker } : {}),
303
+ metrics: {
304
+ tokensIn: r.tokensIn,
305
+ tokensOut: r.tokensOut,
306
+ costUsd: r.costUsd,
307
+ latencyMs: r.latencyMs,
308
+ filesReviewed: r.filesReviewed,
309
+ },
310
+ runFolder: r.runFolder,
311
+ ...(r.shallowWarning ? { shallowWarning: r.shallowWarning } : {}),
312
+ };
313
+ return {
314
+ content: [{ type: "text", text: JSON.stringify(summary, null, 2) }],
315
+ };
316
+ }
317
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almightygpt/core",
3
- "version": "0.8.1",
3
+ "version": "0.9.0",
4
4
  "description": "Core orchestrator, adapters, config, runs, and review logic for AlmightyGPT",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,6 +25,7 @@
25
25
  "dependencies": {
26
26
  "@anthropic-ai/sdk": "^0.30.0",
27
27
  "@google/generative-ai": "^0.21.0",
28
+ "@modelcontextprotocol/sdk": "^1.29.0",
28
29
  "execa": "^9.3.0",
29
30
  "ignore": "^6.0.2",
30
31
  "openai": "^4.52.0",
package/src/index.ts CHANGED
@@ -13,7 +13,10 @@
13
13
  * - budget/ ✅ task #14 BudgetTracker + BudgetExceededError
14
14
  */
15
15
 
16
- export const VERSION = "0.8.1";
16
+ export const VERSION = "0.9.0";
17
+
18
+ // MCP server (v0.9.0+) — exposes AlmightyGPT's review surface as MCP tools.
19
+ export { startMcpServer } from "./mcp/server.js";
17
20
 
18
21
  // Git safety primitives
19
22
  export {
@@ -0,0 +1,361 @@
1
+ /**
2
+ * AlmightyGPT MCP server.
3
+ *
4
+ * Exposes the AlmightyGPT CLI's review/precommit/auth/runs surface as
5
+ * Model Context Protocol tools, so MCP-aware clients (Claude Desktop,
6
+ * Cursor, Continue, etc.) can invoke them directly.
7
+ *
8
+ * Transport: stdio (the default for local MCP servers). Spawned from
9
+ * the user's MCP client config — typically something like:
10
+ *
11
+ * {
12
+ * "mcpServers": {
13
+ * "almightygpt": {
14
+ * "command": "almightygpt",
15
+ * "args": ["mcp", "serve"]
16
+ * }
17
+ * }
18
+ * }
19
+ *
20
+ * Tool surface (v0.9.0):
21
+ * - review_diff: run a Worker/Reviewer or Reviewer-only review on a diff
22
+ * - precommit: quick last-mile review of uncommitted changes
23
+ * - auth_status: see which providers are configured
24
+ * - runs_list: list recent runs
25
+ * - runs_latest: show the most recent run
26
+ *
27
+ * Each tool is a thin wrapper around the existing core functions —
28
+ * no orchestration logic lives here. The CLI and MCP server are
29
+ * peer transports for the same underlying capabilities.
30
+ */
31
+
32
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
33
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
34
+ import {
35
+ CallToolRequestSchema,
36
+ ListToolsRequestSchema,
37
+ } from "@modelcontextprotocol/sdk/types.js";
38
+
39
+ import { runDiffReview } from "../review/run-diff-review.js";
40
+ import { runWorkerReviewerReview } from "../review/run-worker-reviewer.js";
41
+ import { listRuns, findLatestRun } from "../runs/list.js";
42
+ import { resolveApiKey } from "../auth/resolver.js";
43
+ import { PROVIDER_ENV_VARS, type ProviderId } from "../auth/types.js";
44
+ import { loadConfig } from "../config/load.js";
45
+
46
+ const SERVER_NAME = "almightygpt";
47
+
48
+ interface ServeOptions {
49
+ /** Override the cwd the MCP server treats as the repo root. */
50
+ cwd?: string;
51
+ }
52
+
53
+ /**
54
+ * Start the AlmightyGPT MCP server on stdio. Blocks for the lifetime
55
+ * of the process (returns the connect() promise — caller should await
56
+ * it inside the CLI command handler).
57
+ */
58
+ export async function startMcpServer(options: ServeOptions = {}): Promise<void> {
59
+ const repoRoot = options.cwd ?? process.cwd();
60
+ const server = new Server(
61
+ {
62
+ name: SERVER_NAME,
63
+ version: "0.9.0",
64
+ },
65
+ {
66
+ capabilities: {
67
+ tools: {},
68
+ },
69
+ },
70
+ );
71
+
72
+ // Tool list — what clients see when they introspect the server.
73
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
74
+ tools: [
75
+ {
76
+ name: "review_diff",
77
+ description:
78
+ "Run a cross-AI review on a git diff. Use `worker` to enable the " +
79
+ "Worker/Reviewer two-role flow, or omit for reviewer-only. Returns " +
80
+ "the review markdown plus cost/latency metrics.",
81
+ inputSchema: {
82
+ type: "object",
83
+ properties: {
84
+ topic: {
85
+ type: "string",
86
+ description:
87
+ "Topic slug for the review file path (e.g. 'auth-refactor').",
88
+ },
89
+ reviewer: {
90
+ type: "string",
91
+ description:
92
+ "Reviewer agent name. Falls back to config.defaults.reviewer.",
93
+ },
94
+ worker: {
95
+ type: "string",
96
+ description:
97
+ "Worker agent name. If set, runs the two-role flow.",
98
+ },
99
+ range: {
100
+ type: "string",
101
+ description: "Git range like 'HEAD~3..HEAD'. Omit for uncommitted.",
102
+ },
103
+ force: {
104
+ type: "boolean",
105
+ description: "Overwrite existing review file. Default false.",
106
+ },
107
+ },
108
+ required: ["topic"],
109
+ },
110
+ },
111
+ {
112
+ name: "precommit",
113
+ description:
114
+ "Quick last-mile review of uncommitted changes using the configured " +
115
+ "quick reviewer (Gemini Flash by default). Cheap (~$0.003) and fast. " +
116
+ "Returns review markdown + shallow-flag for CI gating.",
117
+ inputSchema: {
118
+ type: "object",
119
+ properties: {
120
+ topic: {
121
+ type: "string",
122
+ description:
123
+ "Topic slug. Defaults to `precommit-<unix-timestamp>` if omitted.",
124
+ },
125
+ reviewer: {
126
+ type: "string",
127
+ description:
128
+ "Override the quick reviewer. Defaults to config.defaults.quickReviewer.",
129
+ },
130
+ range: {
131
+ type: "string",
132
+ description: "Git range. Omit for uncommitted changes.",
133
+ },
134
+ },
135
+ },
136
+ },
137
+ {
138
+ name: "auth_status",
139
+ description:
140
+ "Report which providers (OpenAI, Anthropic, Google) have API keys " +
141
+ "configured, and from where (env var vs keychain vs missing).",
142
+ inputSchema: {
143
+ type: "object",
144
+ properties: {},
145
+ },
146
+ },
147
+ {
148
+ name: "runs_list",
149
+ description:
150
+ "List recent AlmightyGPT runs with cost, status, and timestamps.",
151
+ inputSchema: {
152
+ type: "object",
153
+ properties: {
154
+ limit: {
155
+ type: "number",
156
+ description: "Max runs to return. Default 10.",
157
+ },
158
+ },
159
+ },
160
+ },
161
+ {
162
+ name: "runs_latest",
163
+ description: "Show the most recent run (path to review file + metrics).",
164
+ inputSchema: {
165
+ type: "object",
166
+ properties: {},
167
+ },
168
+ },
169
+ ],
170
+ }));
171
+
172
+ // Tool dispatcher — routes to the right core function.
173
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
174
+ const { name, arguments: args = {} } = request.params;
175
+ const a = args as Record<string, unknown>;
176
+
177
+ try {
178
+ switch (name) {
179
+ case "review_diff": {
180
+ const topic = String(a["topic"]);
181
+ if (!topic) throw new Error("`topic` is required");
182
+ const useWorker = typeof a["worker"] === "string";
183
+
184
+ if (useWorker) {
185
+ const opts: Parameters<typeof runWorkerReviewerReview>[0] = {
186
+ repoRoot,
187
+ topic,
188
+ force: a["force"] === true,
189
+ };
190
+ if (typeof a["range"] === "string") opts.range = a["range"];
191
+ if (typeof a["worker"] === "string") opts.worker = a["worker"];
192
+ if (typeof a["reviewer"] === "string") opts.reviewer = a["reviewer"];
193
+ const result = await runWorkerReviewerReview(opts);
194
+ return formatReviewResult({
195
+ reviewPath: result.reviewPath,
196
+ tokensIn: result.totals.tokensIn,
197
+ tokensOut: result.totals.tokensOut,
198
+ costUsd: result.totals.costUsd,
199
+ latencyMs: result.totals.latencyMs,
200
+ filesReviewed: result.filesReviewed.length,
201
+ runFolder: result.runFolder,
202
+ worker: result.worker.name,
203
+ reviewer: result.reviewer.name,
204
+ });
205
+ }
206
+
207
+ const opts: Parameters<typeof runDiffReview>[0] = {
208
+ repoRoot,
209
+ topic,
210
+ force: a["force"] === true,
211
+ };
212
+ if (typeof a["range"] === "string") opts.range = a["range"];
213
+ if (typeof a["reviewer"] === "string") opts.reviewer = a["reviewer"];
214
+ const result = await runDiffReview(opts);
215
+ return formatReviewResult({
216
+ reviewPath: result.reviewPath,
217
+ tokensIn: result.tokensIn,
218
+ tokensOut: result.tokensOut,
219
+ costUsd: result.costUsd,
220
+ latencyMs: result.latencyMs,
221
+ filesReviewed: result.filesReviewed.length,
222
+ runFolder: result.runFolder,
223
+ reviewer: result.reviewer,
224
+ shallowWarning: result.shallowWarning,
225
+ });
226
+ }
227
+
228
+ case "precommit": {
229
+ const config = await loadConfig(repoRoot);
230
+ const reviewer =
231
+ (typeof a["reviewer"] === "string" && a["reviewer"]) ||
232
+ config.defaults.quickReviewer ||
233
+ config.defaults.reviewer;
234
+ if (!reviewer) {
235
+ throw new Error(
236
+ "No quick reviewer configured. Set defaults.quickReviewer in " +
237
+ ".almightygpt/config.yaml or pass `reviewer`.",
238
+ );
239
+ }
240
+ const topic =
241
+ (typeof a["topic"] === "string" && a["topic"]) ||
242
+ `precommit-${Math.floor(Date.now() / 1000)}`;
243
+ const opts: Parameters<typeof runDiffReview>[0] = {
244
+ repoRoot,
245
+ topic,
246
+ reviewer,
247
+ force: true,
248
+ };
249
+ if (typeof a["range"] === "string") opts.range = a["range"];
250
+ const precommitDir = (config as { precommitDir?: string }).precommitDir;
251
+ if (precommitDir) opts.reviewsDirOverride = precommitDir;
252
+
253
+ const result = await runDiffReview(opts);
254
+ return formatReviewResult({
255
+ reviewPath: result.reviewPath,
256
+ tokensIn: result.tokensIn,
257
+ tokensOut: result.tokensOut,
258
+ costUsd: result.costUsd,
259
+ latencyMs: result.latencyMs,
260
+ filesReviewed: result.filesReviewed.length,
261
+ runFolder: result.runFolder,
262
+ reviewer,
263
+ shallowWarning: result.shallowWarning,
264
+ });
265
+ }
266
+
267
+ case "auth_status": {
268
+ const providers: ProviderId[] = ["openai", "anthropic", "google"];
269
+ const rows = await Promise.all(
270
+ providers.map(async (p) => {
271
+ const r = await resolveApiKey(p);
272
+ return {
273
+ provider: p,
274
+ source: r.source,
275
+ envVar: r.envVar ?? PROVIDER_ENV_VARS[p][0],
276
+ configured: r.source !== "missing",
277
+ };
278
+ }),
279
+ );
280
+ return {
281
+ content: [
282
+ {
283
+ type: "text",
284
+ text: JSON.stringify({ providers: rows }, null, 2),
285
+ },
286
+ ],
287
+ };
288
+ }
289
+
290
+ case "runs_list": {
291
+ const config = await loadConfig(repoRoot);
292
+ const limit = typeof a["limit"] === "number" ? a["limit"] : 10;
293
+ const result = await listRuns({
294
+ repoRoot,
295
+ runsDir: config.runsDir,
296
+ limit,
297
+ });
298
+ return {
299
+ content: [
300
+ { type: "text", text: JSON.stringify(result, null, 2) },
301
+ ],
302
+ };
303
+ }
304
+
305
+ case "runs_latest": {
306
+ const config = await loadConfig(repoRoot);
307
+ const result = await findLatestRun(repoRoot, config.runsDir);
308
+ return {
309
+ content: [
310
+ { type: "text", text: JSON.stringify(result ?? null, null, 2) },
311
+ ],
312
+ };
313
+ }
314
+
315
+ default:
316
+ throw new Error(`Unknown tool: ${name}`);
317
+ }
318
+ } catch (err) {
319
+ const message = err instanceof Error ? err.message : String(err);
320
+ return {
321
+ isError: true,
322
+ content: [{ type: "text", text: `Error: ${message}` }],
323
+ };
324
+ }
325
+ });
326
+
327
+ const transport = new StdioServerTransport();
328
+ await server.connect(transport);
329
+ }
330
+
331
+ /** Compact summary of a review result for MCP clients. */
332
+ function formatReviewResult(r: {
333
+ reviewPath: string;
334
+ tokensIn: number;
335
+ tokensOut: number;
336
+ costUsd: number;
337
+ latencyMs: number;
338
+ filesReviewed: number;
339
+ runFolder: string;
340
+ worker?: string;
341
+ reviewer: string;
342
+ shallowWarning?: string | undefined;
343
+ }) {
344
+ const summary = {
345
+ reviewPath: r.reviewPath,
346
+ reviewer: r.reviewer,
347
+ ...(r.worker ? { worker: r.worker } : {}),
348
+ metrics: {
349
+ tokensIn: r.tokensIn,
350
+ tokensOut: r.tokensOut,
351
+ costUsd: r.costUsd,
352
+ latencyMs: r.latencyMs,
353
+ filesReviewed: r.filesReviewed,
354
+ },
355
+ runFolder: r.runFolder,
356
+ ...(r.shallowWarning ? { shallowWarning: r.shallowWarning } : {}),
357
+ };
358
+ return {
359
+ content: [{ type: "text", text: JSON.stringify(summary, null, 2) }],
360
+ };
361
+ }