From 3623c5095354744d412246f5b4f9a44f6fec8e6d Mon Sep 17 00:00:00 2001 From: hermes Date: Thu, 15 Oct 2026 05:29:02 +0000 Subject: [PATCH] fix(web): address PR review (clean .md output, one MCP config source) - .md output rewrites MDX-only syntax (Tabs, TabItem, asides, the MCP client component) into plain Markdown. - MCP client setups live in one data file used by the landing page, the setup page and agents/install; the smoke-test claim names the five agents agent-smoke.sh actually drives (not Cursor). - The landing page reads the version from Cargo.toml; the hand-copied BBCA data stays dated, and the design doc no longer promises capture.sh. - MCP overview counts 11 tools plus the opt-in ownership_sync. Co-Authored-By: Claude Opus 5.5 --- web/DESIGN.md | 4 +- web/src/components/McpClientTabs.astro | 15 ++++ .../docs/agents/{install.md => install.mdx} | 22 ++--- web/src/content/docs/mcp/index.md | 2 +- web/src/content/docs/mcp/setup.mdx | 89 +------------------ web/src/data/mcp-clients.ts | 32 +++++++ web/src/pages/[...slug].md.ts | 30 ++++++- web/src/pages/index.astro | 24 +++-- 8 files changed, 99 insertions(+), 119 deletions(-) create mode 100644 web/src/components/McpClientTabs.astro rename web/src/content/docs/agents/{install.md => install.mdx} (71%) create mode 100644 web/src/data/mcp-clients.ts diff --git a/web/DESIGN.md b/web/DESIGN.md index 80b5126..dc0f343 100644 --- a/web/DESIGN.md +++ b/web/DESIGN.md @@ -120,7 +120,7 @@ stack. | --- | --- | --- | | `/cli/reference` | `idx --help` per command | a script runs the built binary and writes Markdown | | `/mcp/tools` | `crates/idx-mcp/tests/golden/tools.json` | rendered at build time from the golden | -| Terminal panels | real `idx` runs | `web/scripts/capture.sh` saves output with a date; refreshed by hand | +| Terminal panels, BBCA table | real `idx` runs | copied by hand and labelled with their date; refresh after a new month | | Install, guides | hand-written | reviewed when the README changes | The README shrinks to a pitch, one install line per channel, and a link to the @@ -167,7 +167,7 @@ lives: - **Hermes:** `config.yaml`, `mcp_servers.idx`. - **Other:** the `idx-mcp` command over stdio. -These configs are the ones `tests/agents/agent-smoke.sh` already runs, so the +The Claude Code, Codex, opencode, pi and Hermes configs are the ones `tests/agents/agent-smoke.sh` already runs, so the site can link that script as proof they work. ## Stack diff --git a/web/src/components/McpClientTabs.astro b/web/src/components/McpClientTabs.astro new file mode 100644 index 0000000..208a70e --- /dev/null +++ b/web/src/components/McpClientTabs.astro @@ -0,0 +1,15 @@ +--- +import { Code, TabItem, Tabs } from '@astrojs/starlight/components'; +import { mcpClients } from '../data/mcp-clients'; +--- + + + { + mcpClients.map((c) => ( + +

{/[~/]/.test(c.file) ? {c.file} : c.file}

+ +
+ )) + } +
diff --git a/web/src/content/docs/agents/install.md b/web/src/content/docs/agents/install.mdx similarity index 71% rename from web/src/content/docs/agents/install.md rename to web/src/content/docs/agents/install.mdx index 2024269..83e40a1 100644 --- a/web/src/content/docs/agents/install.md +++ b/web/src/content/docs/agents/install.mdx @@ -3,6 +3,8 @@ title: Agent-led install description: Instructions for a coding agent to install idx and register idx-mcp with itself. --- +import McpClientTabs from '../../../components/McpClientTabs.astro'; + This page is written for a coding agent. A user sent you here to install **idx** (a CLI for Indonesian stock market and KSEI ownership data) and register its MCP server, **idx-mcp**, with the agent harness you are running @@ -44,22 +46,14 @@ Confirm with `idx version` (or `npx -y idx-cli version`). ## 3. Register idx-mcp with yourself -Work out which harness you are, then apply its setup. Use `npx` and -`["-y", "idx-mcp"]` as command and arguments, or `idx-mcp` with no arguments -if you installed the binary. +Work out which harness you are, then apply its setup below. If you installed +the `idx-mcp` binary instead of using Node.js, use the command `idx-mcp` with +no arguments in place of `npx -y idx-mcp`. For any other harness, find how it +registers a stdio MCP server, and ask the user if unsure. -| Harness | How | -| --- | --- | -| Claude Code | run `claude mcp add idx -- npx -y idx-mcp` | -| Codex | add to `~/.codex/config.toml`: `[mcp_servers.idx]` with `command = "npx"`, `args = ["-y", "idx-mcp"]` | -| Cursor | add to `~/.cursor/mcp.json` under `mcpServers`: `"idx": {"command": "npx", "args": ["-y", "idx-mcp"]}` | -| opencode | add to `~/.config/opencode/opencode.json` under `mcp`: `"idx": {"type": "local", "command": ["npx", "-y", "idx-mcp"], "enabled": true}` | -| pi | add to `~/.pi/agent/mcp.json` under `mcpServers`: `"idx": {"command": "npx", "args": ["-y", "idx-mcp"], "exposure": "direct"}` | -| Hermes | add to `~/.hermes/config.yaml` under `mcp_servers`: `idx` with `command: npx`, `args: ["-y", "idx-mcp"]`, `enabled: true` | -| anything else | find how your harness registers a stdio MCP server, and ask the user if unsure | + -Merge into existing files; never overwrite other servers or settings. Full -examples: [MCP setup](/mcp/setup/). +Merge into existing files; never overwrite other servers or settings. ## 4. Download ownership data diff --git a/web/src/content/docs/mcp/index.md b/web/src/content/docs/mcp/index.md index 4ce67e2..d34a6e7 100644 --- a/web/src/content/docs/mcp/index.md +++ b/web/src/content/docs/mcp/index.md @@ -5,7 +5,7 @@ description: idx-mcp serves idx's stock and ownership data to AI agents over MCP `idx-mcp` is a [Model Context Protocol](https://modelcontextprotocol.io) server over stdio. It gives an agent the same data as the `idx` CLI, as -[11 tools](/mcp/tools/): quotes, price history, screening, company data, +[11 tools](/mcp/tools/) (plus an opt-in `ownership_sync`): quotes, price history, screening, company data, analysis, comparison, and the KSEI ownership queries. It shares idx's [config, cache and ownership database](/start/config/#files-idx-keeps), diff --git a/web/src/content/docs/mcp/setup.mdx b/web/src/content/docs/mcp/setup.mdx index fbe0c85..a21fb63 100644 --- a/web/src/content/docs/mcp/setup.mdx +++ b/web/src/content/docs/mcp/setup.mdx @@ -5,7 +5,7 @@ sidebar: label: Setup --- -import { Tabs, TabItem } from '@astrojs/starlight/components'; +import McpClientTabs from '../../../components/McpClientTabs.astro'; :::tip[Quickest: let your agent do it] Paste this into your coding agent. It follows @@ -33,91 +33,10 @@ nix profile install github:0xrsydn/idx-cli#idx-mcp ## 2. Add it to your client - - + -```bash -claude mcp add idx -- npx -y idx-mcp -``` - - - - -`~/.codex/config.toml`: - -```toml -[mcp_servers.idx] -command = "npx" -args = ["-y", "idx-mcp"] -``` - - - - -`~/.cursor/mcp.json` (or `.cursor/mcp.json` in a project): - -```json -{ - "mcpServers": { - "idx": { "command": "npx", "args": ["-y", "idx-mcp"] } - } -} -``` - - - - -`opencode.json` in a project, or `~/.config/opencode/opencode.json`: - -```json -{ - "$schema": "https://opencode.ai/config.json", - "mcp": { - "idx": { "type": "local", "command": ["npx", "-y", "idx-mcp"], "enabled": true } - } -} -``` - - - - -`~/.pi/agent/mcp.json`: - -```json -{ - "mcpServers": { - "idx": { "command": "npx", "args": ["-y", "idx-mcp"], "exposure": "direct" } - } -} -``` - -`"exposure": "direct"` gives the agent each tool by name. - - - - -`~/.hermes/config.yaml`: - -```yaml -mcp_servers: - idx: - command: npx - args: ["-y", "idx-mcp"] - enabled: true -``` - - - - -Any MCP client that runs stdio servers: command `npx`, arguments -`-y idx-mcp` (or the command `idx-mcp` if installed). Add `--allow-sync` to -the arguments to expose `ownership_sync`. - - - - -These are the setups that `tests/agents/agent-smoke.sh` drives with real -agents. +The Claude Code, Codex, opencode, pi and Hermes setups are the ones +`tests/agents/agent-smoke.sh` drives with the real agents. ## 3. Get ownership data diff --git a/web/src/data/mcp-clients.ts b/web/src/data/mcp-clients.ts new file mode 100644 index 0000000..a76038b --- /dev/null +++ b/web/src/data/mcp-clients.ts @@ -0,0 +1,32 @@ +// The one list of MCP client setups, used by the landing page, the MCP setup +// page and agents/install.md (and their .md output). + +export interface McpClient { + id: string; + label: string; + /** Where the config goes, shown above the snippet. */ + file: string; + lang: string; + code: string; + /** Driven by tests/agents/agent-smoke.sh against the real agent. */ + smokeTested: boolean; +} + +export const mcpClients: McpClient[] = [ + { id: 'claude', label: 'Claude Code', file: 'Run in a terminal', lang: 'bash', smokeTested: true, code: 'claude mcp add idx -- npx -y idx-mcp' }, + { id: 'codex', label: 'Codex', file: '~/.codex/config.toml', lang: 'toml', smokeTested: true, code: '[mcp_servers.idx]\ncommand = "npx"\nargs = ["-y", "idx-mcp"]' }, + { id: 'cursor', label: 'Cursor', file: '~/.cursor/mcp.json (or .cursor/mcp.json in a project)', lang: 'json', smokeTested: false, code: '{\n "mcpServers": {\n "idx": { "command": "npx", "args": ["-y", "idx-mcp"] }\n }\n}' }, + { id: 'opencode', label: 'opencode', file: '~/.config/opencode/opencode.json (or opencode.json in a project)', lang: 'json', smokeTested: true, code: '{\n "$schema": "https://opencode.ai/config.json",\n "mcp": {\n "idx": { "type": "local", "command": ["npx", "-y", "idx-mcp"], "enabled": true }\n }\n}' }, + { id: 'pi', label: 'pi', file: '~/.pi/agent/mcp.json', lang: 'json', smokeTested: true, code: '{\n "mcpServers": {\n "idx": { "command": "npx", "args": ["-y", "idx-mcp"], "exposure": "direct" }\n }\n}' }, + { id: 'hermes', label: 'Hermes', file: '~/.hermes/config.yaml', lang: 'yaml', smokeTested: true, code: 'mcp_servers:\n idx:\n command: npx\n args: ["-y", "idx-mcp"]\n enabled: true' }, + { id: 'other', label: 'Other', file: 'Any MCP client that runs stdio servers', lang: 'text', smokeTested: false, code: 'command: npx\nargs: -y idx-mcp\n# or the command idx-mcp, if installed\n# add --allow-sync to expose ownership_sync' }, +]; + +export const smokeTestedLabels = mcpClients.filter((c) => c.smokeTested).map((c) => c.label); + +/** The setups as Markdown, for the .md output of pages that render . */ +export function mcpClientsMarkdown(): string { + return mcpClients + .map((c) => `### ${c.label}\n\n${c.file}:\n\n\`\`\`${c.lang}\n${c.code}\n\`\`\``) + .join('\n\n'); +} diff --git a/web/src/pages/[...slug].md.ts b/web/src/pages/[...slug].md.ts index cdcfe20..aa92eef 100644 --- a/web/src/pages/[...slug].md.ts +++ b/web/src/pages/[...slug].md.ts @@ -1,15 +1,37 @@ -// Serves every docs page as raw Markdown at `.md`, so agents can read -// the docs without HTML (for example /agents/install.md). +// Serves every docs page as plain Markdown at `.md`, so agents can read +// the docs without HTML (for example /agents/install.md). MDX-only syntax is +// rewritten into Markdown. import type { APIRoute, GetStaticPaths } from 'astro'; import { getCollection } from 'astro:content'; +import { mcpClientsMarkdown } from '../data/mcp-clients'; export const getStaticPaths: GetStaticPaths = async () => { const docs = await getCollection('docs'); return docs.map((entry) => ({ params: { slug: entry.id }, props: { entry } })); }; +function toPlainMarkdown(title: string, body: string): string { + const text = body + .replace(/\n*/g, '') + .replace(/^import .*\n+/gm, '') + .replace(/^$/gm, () => mcpClientsMarkdown()) + // : each becomes a bold label. + .replace(/^<\/?Tabs[^>]*>\n*/gm, '') + .replace(/^$/gm, '**$1**') + .replace(/^<\/TabItem>\n*/gm, '') + // Asides (:::tip[Title] ... :::) become blockquote-free sections. + .replace(/^:::\w+\[([^\]]+)\]$/gm, '**$1**\n') + .replace(/^:::\w+$/gm, '') + .replace(/^:::$/gm, '') + .replace(/^```(\w+) wrap$/gm, '```$1') + .replace(/\n{3,}/g, '\n\n') + .trim(); + return `# ${title}\n\n${text}\n`; +} + export const GET: APIRoute = ({ props }) => { const { entry } = props; - const body = `# ${entry.data.title}\n\n${entry.body ?? ''}`.replace(/\n*/g, '').replace(/^import .*\n+/gm, ''); - return new Response(body, { headers: { 'Content-Type': 'text/markdown; charset=utf-8' } }); + return new Response(toPlainMarkdown(entry.data.title, entry.body ?? ''), { + headers: { 'Content-Type': 'text/markdown; charset=utf-8' }, + }); }; diff --git a/web/src/pages/index.astro b/web/src/pages/index.astro index 1497228..b1acdb0 100644 --- a/web/src/pages/index.astro +++ b/web/src/pages/index.astro @@ -4,6 +4,11 @@ import '@fontsource/ibm-plex-sans/600.css'; import '@fontsource/ibm-plex-sans/700.css'; import '@fontsource/jetbrains-mono/400.css'; import '@fontsource/jetbrains-mono/700.css'; +import { readFileSync } from 'node:fs'; +import { mcpClients, smokeTestedLabels } from '../data/mcp-clients'; + +// The released version, from the workspace Cargo.toml (builds run in web/). +const version = readFileSync('../Cargo.toml', 'utf8').match(/^version = "([^"]+)"/m)?.[1] ?? ''; const agentPrompt = 'Install idx-cli and its MCP server for me by following https://idx.rasyidanaf.com/agents/install.md, then show me that it works.'; @@ -16,17 +21,10 @@ const installs = [ { id: 'agent', label: 'Ask your agent', cmd: agentPrompt, prompt: true, note: 'Paste into Claude Code, Codex, Cursor or any coding agent. It installs idx, registers idx-mcp with itself, and asks before changing global config.' }, ]; -const agents = [ - { id: 'claude', label: 'Claude Code', file: 'terminal', code: 'claude mcp add idx -- npx -y idx-mcp' }, - { id: 'codex', label: 'Codex', file: '~/.codex/config.toml', code: '[mcp_servers.idx]\ncommand = "npx"\nargs = ["-y", "idx-mcp"]' }, - { id: 'cursor', label: 'Cursor', file: '~/.cursor/mcp.json', code: '{\n "mcpServers": {\n "idx": { "command": "npx", "args": ["-y", "idx-mcp"] }\n }\n}' }, - { id: 'opencode', label: 'opencode', file: 'opencode.json', code: '{\n "mcp": {\n "idx": { "type": "local", "command": ["npx", "-y", "idx-mcp"] }\n }\n}' }, - { id: 'pi', label: 'pi', file: '~/.pi/agent/mcp.json', code: '{\n "mcpServers": {\n "idx": { "command": "npx", "args": ["-y", "idx-mcp"], "exposure": "direct" }\n }\n}' }, - { id: 'hermes', label: 'Hermes', file: '~/.hermes/config.yaml', code: 'mcp_servers:\n idx:\n command: npx\n args: ["-y", "idx-mcp"]\n enabled: true' }, - { id: 'other', label: 'Other', file: 'any MCP client (stdio)', code: 'command: npx\nargs: -y idx-mcp\n# add --allow-sync to expose ownership_sync' }, -]; +const agents = mcpClients; -// Captured from `idx ownership ticker BBCA` on the 2026-09-30 snapshot. +// Captured by hand from `idx ownership ticker BBCA` on the 2026-09-30 snapshot; +// the section shows that date. Refresh it (and the terminal panel) after a new month. const holders = [ { name: 'DWIMURIA INVESTAMA ANDALAN', type: 'Corporate', shares: '67,729,950,000', pct: 54.94 }, { name: 'ANTHONI SALIM', type: 'Individual', shares: '1,416,306,835', pct: 1.15 }, @@ -69,7 +67,7 @@ const copyIcon =
-
v0.3.1 · Rust · MIT
+
v{version} · Rust · MIT

Indonesian stocks and ownership, in your terminal and your agent.

Quotes, fundamentals, technicals and KSEI shareholder data for every IDX stock. Tables for you, JSON for scripts, and an MCP server for AI agents.

@@ -143,7 +141,7 @@ TLKM.JK 2,250 +0.45% 87,159,900

Add idx to your agent

-

idx-mcp serves the same data over stdio. Each setup below is the one our agent smoke test runs against real agents.

+

idx-mcp serves the same data over stdio. Our agent smoke test runs the {new Intl.ListFormat("en", { type: "conjunction" }).format(smokeTestedLabels)} setups against the real agents.

Ask it
"Who are BBCA's largest holders, and what changed last month?"
@@ -156,7 +154,7 @@ TLKM.JK 2,250 +0.45% 87,159,900
- See all 11 tools → + See all tools →