mirror of
https://github.com/0xrsydn/idx-cli.git
synced 2026-11-07 01:35:36 +00:00
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 <noreply@anthropic.com>
This commit is contained in:
parent
e6805474f5
commit
3623c50953
8 changed files with 101 additions and 121 deletions
|
|
@ -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
|
||||
|
|
|
|||
15
web/src/components/McpClientTabs.astro
Normal file
15
web/src/components/McpClientTabs.astro
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
import { Code, TabItem, Tabs } from '@astrojs/starlight/components';
|
||||
import { mcpClients } from '../data/mcp-clients';
|
||||
---
|
||||
|
||||
<Tabs syncKey="agent">
|
||||
{
|
||||
mcpClients.map((c) => (
|
||||
<TabItem label={c.label}>
|
||||
<p>{/[~/]/.test(c.file) ? <code>{c.file}</code> : c.file}</p>
|
||||
<Code code={c.code} lang={c.lang} />
|
||||
</TabItem>
|
||||
))
|
||||
}
|
||||
</Tabs>
|
||||
|
|
@ -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 |
|
||||
<McpClientTabs />
|
||||
|
||||
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
|
||||
|
||||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
<Tabs syncKey="agent">
|
||||
<TabItem label="Claude Code">
|
||||
<McpClientTabs />
|
||||
|
||||
```bash
|
||||
claude mcp add idx -- npx -y idx-mcp
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Codex">
|
||||
|
||||
`~/.codex/config.toml`:
|
||||
|
||||
```toml
|
||||
[mcp_servers.idx]
|
||||
command = "npx"
|
||||
args = ["-y", "idx-mcp"]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Cursor">
|
||||
|
||||
`~/.cursor/mcp.json` (or `.cursor/mcp.json` in a project):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"idx": { "command": "npx", "args": ["-y", "idx-mcp"] }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="opencode">
|
||||
|
||||
`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 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="pi">
|
||||
|
||||
`~/.pi/agent/mcp.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"idx": { "command": "npx", "args": ["-y", "idx-mcp"], "exposure": "direct" }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`"exposure": "direct"` gives the agent each tool by name.
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Hermes">
|
||||
|
||||
`~/.hermes/config.yaml`:
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
idx:
|
||||
command: npx
|
||||
args: ["-y", "idx-mcp"]
|
||||
enabled: true
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem label="Other">
|
||||
|
||||
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`.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
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
|
||||
|
||||
|
|
|
|||
32
web/src/data/mcp-clients.ts
Normal file
32
web/src/data/mcp-clients.ts
Normal file
|
|
@ -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 <McpClientTabs />. */
|
||||
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');
|
||||
}
|
||||
|
|
@ -1,15 +1,37 @@
|
|||
// Serves every docs page as raw Markdown at `<path>.md`, so agents can read
|
||||
// the docs without HTML (for example /agents/install.md).
|
||||
// Serves every docs page as plain Markdown at `<path>.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(/<!--[\s\S]*?-->\n*/g, '')
|
||||
.replace(/^import .*\n+/gm, '')
|
||||
.replace(/^<McpClientTabs \/>$/gm, () => mcpClientsMarkdown())
|
||||
// <Tabs>: each <TabItem label="X"> becomes a bold label.
|
||||
.replace(/^<\/?Tabs[^>]*>\n*/gm, '')
|
||||
.replace(/^<TabItem label="([^"]+)">$/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(/<!--[\s\S]*?-->\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' },
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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 =
|
|||
<main>
|
||||
<section class="wrap hero">
|
||||
<div class="hero-text">
|
||||
<div class="eyebrow">v0.3.1 · Rust · MIT</div>
|
||||
<div class="eyebrow">v{version} · Rust · MIT</div>
|
||||
<h1>Indonesian stocks and ownership, in your terminal and your agent.</h1>
|
||||
<p class="lede">Quotes, fundamentals, technicals and KSEI shareholder data for every IDX stock. Tables for you, JSON for scripts, and an MCP server for AI agents.</p>
|
||||
|
||||
|
|
@ -143,7 +141,7 @@ TLKM.JK 2,250 <span class="up">+0.45%</span> 87,159,900
|
|||
<section id="agents" class="wrap split">
|
||||
<div class="side">
|
||||
<h2 class="h2">Add idx to your agent</h2>
|
||||
<p class="muted-p">idx-mcp serves the same data over stdio. Each setup below is the one our agent smoke test runs against real agents.</p>
|
||||
<p class="muted-p">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.</p>
|
||||
<div class="card">
|
||||
<div class="label">Ask it</div>
|
||||
<div class="ask">"Who are BBCA's largest holders, and what changed last month?"</div>
|
||||
|
|
@ -156,7 +154,7 @@ TLKM.JK 2,250 <span class="up">+0.45%</span> 87,159,900
|
|||
<button type="button" class="copy" data-copy={agentPrompt} aria-label="Copy agent prompt" set:html={copyIcon} />
|
||||
</div>
|
||||
</div>
|
||||
<a class="more" href="/mcp/tools/">See all 11 tools →</a>
|
||||
<a class="more" href="/mcp/tools/">See all tools →</a>
|
||||
</div>
|
||||
|
||||
<div class="main-col tabs" data-tabs>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue