Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions packages/gittensory-miner/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,27 @@ It exposes these read-only tools:

Further AMS-state-reading tools (status/doctor diagnostics) land as follow-up PRs on top of this server.

### Client config

`gittensory-mcp` (ORB's hosted contributor-workflow tools) and `gittensory-miner-mcp` (AMS's own local state-visibility tools above) can run as two separate stdio servers in the same MCP client session — useful for a dual-role operator running both ORB and AMS on the same box. Generate ORB's half with `gittensory-mcp init-client --print claude` (see the [`@jsonbored/gittensory-mcp` README](../gittensory-mcp/README.md#client-config)); `gittensory-miner-mcp` takes no flags, so its entry is just the bin name. Combined, a Claude Desktop / Claude Code style config looks like:

```json
{
"mcpServers": {
"gittensory": {
"command": "gittensory-mcp",
"args": ["--stdio"]
},
"gittensory-miner": {
"command": "gittensory-miner-mcp",
"args": []
}
}
}
```

`gittensory` exposes ORB's hosted contributor-workflow tools (issue ranking, PR packet prep, decision packs). `gittensory-miner` exposes AMS's own local state-visibility tools listed above (portfolio dashboard, claims, audit feed, run state, plans) — a fully separate, 100% local tool surface with no shared code or network calls between the two.

## Version check

On every invocation the CLI starts an async npm registry lookup (5s timeout). When the installed package is behind `@jsonbored/gittensory-miner@latest`, it prints a one-line upgrade command to stderr without blocking or failing the requested command. Set `GITTENSORY_NPM_REGISTRY_URL` to point at a mirror, same as `@jsonbored/gittensory-mcp`.
47 changes: 47 additions & 0 deletions test/unit/miner-mcp-client-config-doc.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";

const README_PATH = join(process.cwd(), "packages/gittensory-miner/README.md");
const MCP_README_PATH = join(process.cwd(), "packages/gittensory-mcp/README.md");

/** Pulls the first ```json fenced block out of a markdown doc. Throws if none is found, so a doc edit that
* accidentally drops the fence (rather than its content) fails loudly instead of silently skipping. */
function extractFirstJsonBlock(markdown: string): string {
const match = markdown.match(/```json\r?\n([\s\S]*?)\r?\n```/);
if (!match || match[1] === undefined) throw new Error("No ```json fenced block found in the given markdown.");
return match[1];
}

describe("miner MCP client config example (#5163)", () => {
it("documents running gittensory-mcp and gittensory-miner-mcp together", () => {
const readme = readFileSync(README_PATH, "utf8");
expect(readme).toContain("### Client config");
expect(readme).toContain("gittensory-mcp init-client --print claude");
// Explains what each server is for, not just how to wire it up.
expect(readme).toContain("contributor-workflow tools");
expect(readme).toContain("state-visibility tools");
});

it("ships a copy-pasteable, valid mcpServers JSON snippet registering both servers", () => {
const readme = readFileSync(README_PATH, "utf8");
const config = JSON.parse(extractFirstJsonBlock(readme));

expect(config.mcpServers.gittensory).toEqual({
command: "gittensory-mcp",
args: ["--stdio"],
});
expect(config.mcpServers["gittensory-miner"]).toEqual({
command: "gittensory-miner-mcp",
args: [],
});
});

it("cross-references the ORB MCP README's own Client config section", () => {
const readme = readFileSync(README_PATH, "utf8");
expect(readme).toContain("../gittensory-mcp/README.md#client-config");

const mcpReadme = readFileSync(MCP_README_PATH, "utf8");
expect(mcpReadme).toContain("### Client config");
});
});