Skip to content

Commit 9ddd03f

Browse files
QuantGeekDevclaude
andcommitted
feat: rename CLI to create-docs-mcp and publish @mcpframework/docs
- Rename create-docs-server → create-docs-mcp CLI command - Update package name to @mcpframework/docs (mcpframework npm org) - Update all references in README, templates, and source - Add @mcpframework/docs section to main README with full usage guide Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent bff2347 commit 9ddd03f

File tree

7 files changed

+183
-16
lines changed

7 files changed

+183
-16
lines changed

README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,72 @@ class CustomAuthProvider implements AuthProvider {
844844
}
845845
```
846846
847+
## Documentation MCP Servers (`@mcpframework/docs`)
848+
849+
Spin up an MCP documentation server from any Fumadocs site or any site with `llms.txt` — AI agents get tools to search, browse, and retrieve your docs.
850+
851+
### Quick Start (CLI)
852+
853+
```bash
854+
# Scaffold a new docs MCP server project
855+
npx create-docs-mcp my-api-docs
856+
cd my-api-docs
857+
858+
# Configure your docs site URL
859+
cp .env.example .env
860+
# Edit .env → set DOCS_BASE_URL=https://docs.myapi.com
861+
862+
# Build and run
863+
npm run build
864+
npm start
865+
```
866+
867+
### Quick Start (Programmatic)
868+
869+
```typescript
870+
import { DocsServer, FumadocsRemoteSource } from "@mcpframework/docs";
871+
872+
const source = new FumadocsRemoteSource({
873+
baseUrl: "https://docs.myapi.com",
874+
});
875+
876+
const server = new DocsServer({
877+
source,
878+
name: "my-api-docs",
879+
version: "1.0.0",
880+
});
881+
882+
server.start();
883+
```
884+
885+
### Source Adapters
886+
887+
| Adapter | Best For | Search |
888+
|---------|----------|--------|
889+
| `FumadocsRemoteSource` | Fumadocs sites | Native Orama search with fallback |
890+
| `LlmsTxtSource` | Any site with `llms.txt` | Local text matching |
891+
| Custom `DocSource` | Any documentation backend | Your implementation |
892+
893+
### Built-in MCP Tools
894+
895+
| Tool | Description |
896+
|------|-------------|
897+
| `search_docs` | Search documentation by keyword or phrase |
898+
| `get_page` | Retrieve full markdown content of a page |
899+
| `list_sections` | Browse the documentation tree structure |
900+
901+
### Add to Your MCP Client
902+
903+
```bash
904+
# Claude Code
905+
claude mcp add my-api-docs -- node /path/to/my-api-docs/dist/index.js
906+
907+
# Or with environment variable
908+
claude mcp add my-api-docs -e DOCS_BASE_URL=https://docs.myapi.com -- node /path/to/my-api-docs/dist/index.js
909+
```
910+
911+
For Claude Desktop / Cursor configuration and full documentation, see the [@mcpframework/docs README](./packages/docs/README.md).
912+
847913
## License
848914
849915
MIT

packages/docs/README.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# @mcp-framework/docs
1+
# @mcpframework/docs
22

33
Spin up an MCP documentation server from your Fumadocs site (or any site with `llms.txt`) in minutes. AI agents in Claude Code, Cursor, or any MCP client get tools to search, browse, and retrieve your documentation — enabling them to write correct integration code on the first try.
44

@@ -7,7 +7,7 @@ Built on top of [mcp-framework](https://github.com/QuantGeekDev/mcp-framework).
77
## Quick Start
88

99
```typescript
10-
import { DocsServer, FumadocsRemoteSource } from "@mcp-framework/docs";
10+
import { DocsServer, FumadocsRemoteSource } from "@mcpframework/docs";
1111

1212
const source = new FumadocsRemoteSource({
1313
baseUrl: "https://docs.myapi.com",
@@ -25,7 +25,7 @@ server.start();
2525
Or scaffold a project instantly:
2626

2727
```bash
28-
npx create-docs-server my-api-docs
28+
npx create-docs-mcp my-api-docs
2929
```
3030

3131
## Sources
@@ -35,7 +35,7 @@ npx create-docs-server my-api-docs
3535
Purpose-built for [Fumadocs](https://fumadocs.vercel.app/) sites. Uses the native Orama search API for high-quality results, with automatic fallback to local text search.
3636

3737
```typescript
38-
import { FumadocsRemoteSource } from "@mcp-framework/docs";
38+
import { FumadocsRemoteSource } from "@mcpframework/docs";
3939

4040
const source = new FumadocsRemoteSource({
4141
baseUrl: "https://docs.myapi.com", // Required
@@ -63,7 +63,7 @@ const source = new FumadocsRemoteSource({
6363
Works with any documentation site that publishes `llms.txt` and `llms-full.txt` files (Fumadocs, Docusaurus with plugin, etc.). Search is performed locally via text matching.
6464

6565
```typescript
66-
import { LlmsTxtSource } from "@mcp-framework/docs";
66+
import { LlmsTxtSource } from "@mcpframework/docs";
6767

6868
const source = new LlmsTxtSource({
6969
baseUrl: "https://docs.myapi.com",
@@ -169,7 +169,7 @@ Add to your MCP settings:
169169
Implement the `DocSource` interface to create adapters for any documentation backend:
170170

171171
```typescript
172-
import { DocSource, DocPage, DocSearchResult, DocSection } from "@mcp-framework/docs";
172+
import { DocSource, DocPage, DocSearchResult, DocSection } from "@mcpframework/docs";
173173

174174
class MyCustomSource implements DocSource {
175175
name = "my-source";
@@ -208,7 +208,7 @@ class MyCustomSource implements DocSource {
208208
The built-in `MemoryCache` provides LRU eviction with TTL expiry. You can pass a custom cache:
209209

210210
```typescript
211-
import { MemoryCache, LlmsTxtSource } from "@mcp-framework/docs";
211+
import { MemoryCache, LlmsTxtSource } from "@mcpframework/docs";
212212

213213
const cache = new MemoryCache({
214214
maxEntries: 200, // Default: 100
@@ -235,12 +235,12 @@ import {
235235
SearchDocsTool,
236236
GetPageTool,
237237
ListSectionsTool,
238-
} from "@mcp-framework/docs";
238+
} from "@mcpframework/docs";
239239

240240
// Subpath imports
241-
import { LlmsTxtSource, FumadocsRemoteSource } from "@mcp-framework/docs/sources";
242-
import { SearchDocsTool, GetPageTool, ListSectionsTool } from "@mcp-framework/docs/tools";
243-
import { MemoryCache } from "@mcp-framework/docs/cache";
241+
import { LlmsTxtSource, FumadocsRemoteSource } from "@mcpframework/docs/sources";
242+
import { SearchDocsTool, GetPageTool, ListSectionsTool } from "@mcpframework/docs/tools";
243+
import { MemoryCache } from "@mcpframework/docs/cache";
244244
```
245245

246246
## License

packages/docs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
2-
"name": "@mcp-framework/docs",
2+
"name": "@mcpframework/docs",
33
"version": "0.1.0",
44
"description": "MCP documentation server framework — spin up an MCP server from your Fumadocs site or llms.txt",
55
"type": "module",
66
"main": "./dist/index.js",
77
"types": "./dist/index.d.ts",
88
"bin": {
9-
"create-docs-server": "./dist/cli/create-docs-server.js"
9+
"create-docs-mcp": "./dist/cli/create-docs-mcp.js"
1010
},
1111
"exports": {
1212
".": {
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#!/usr/bin/env node
2+
3+
import { mkdir, writeFile, readFile } from 'fs/promises';
4+
import { join, dirname } from 'path';
5+
import { fileURLToPath } from 'url';
6+
import { spawnSync } from 'child_process';
7+
8+
const __dirname = dirname(fileURLToPath(import.meta.url));
9+
// Templates are at the package root /templates/ (two levels up from dist/cli/)
10+
const templateDir = join(__dirname, '..', '..', 'templates');
11+
12+
async function main() {
13+
const projectName = process.argv[2];
14+
15+
if (!projectName) {
16+
console.error('Usage: create-docs-mcp <project-name>');
17+
console.error('');
18+
console.error('Example:');
19+
console.error(' npx create-docs-mcp my-api-docs');
20+
process.exit(1);
21+
}
22+
23+
if (!/^[a-z0-9-]+$/.test(projectName)) {
24+
console.error('Error: Project name can only contain lowercase letters, numbers, and hyphens');
25+
process.exit(1);
26+
}
27+
28+
const projectDir = join(process.cwd(), projectName);
29+
const srcDir = join(projectDir, 'src');
30+
31+
console.log(`Creating docs MCP server: ${projectName}`);
32+
33+
try {
34+
await mkdir(projectDir);
35+
await mkdir(srcDir);
36+
37+
// Read and process templates
38+
const templates: Array<{ src: string; dest: string }> = [
39+
{ src: 'index.ts.template', dest: join(srcDir, 'index.ts') },
40+
{ src: 'package.json.template', dest: join(projectDir, 'package.json') },
41+
{ src: 'tsconfig.json.template', dest: join(projectDir, 'tsconfig.json') },
42+
{ src: 'env.example.template', dest: join(projectDir, '.env.example') },
43+
{ src: 'README.md.template', dest: join(projectDir, 'README.md') },
44+
];
45+
46+
for (const t of templates) {
47+
let content = await readFile(join(templateDir, t.src), 'utf-8');
48+
content = content.replace(/\{\{PROJECT_NAME\}\}/g, projectName);
49+
await writeFile(t.dest, content);
50+
}
51+
52+
// Create .gitignore
53+
await writeFile(
54+
join(projectDir, '.gitignore'),
55+
'node_modules\ndist\n.env\n*.log\n.DS_Store\n'
56+
);
57+
58+
// Init git
59+
console.log('Initializing git repository...');
60+
spawnSync('git', ['init'], { cwd: projectDir, stdio: 'inherit', shell: true });
61+
62+
// Install deps
63+
console.log('Installing dependencies...');
64+
const install = spawnSync('npm', ['install'], {
65+
cwd: projectDir,
66+
stdio: 'inherit',
67+
shell: true,
68+
});
69+
70+
if (install.status !== 0) {
71+
console.error('Warning: npm install failed. Run it manually after setup.');
72+
} else {
73+
// Build
74+
console.log('Building project...');
75+
spawnSync('npx', ['tsc'], { cwd: projectDir, stdio: 'inherit', shell: true });
76+
}
77+
78+
console.log(`
79+
Done! Your docs MCP server is ready.
80+
81+
Next steps:
82+
cd ${projectName}
83+
cp .env.example .env
84+
# Edit .env with your documentation site URL
85+
npm run build
86+
npm start
87+
88+
Add to Claude Code:
89+
claude mcp add ${projectName} -- node $(pwd)/${projectName}/dist/index.js
90+
`);
91+
} catch (error: any) {
92+
if (error.code === 'EEXIST') {
93+
console.error(`Error: Directory "${projectName}" already exists`);
94+
} else {
95+
console.error('Error creating project:', error.message);
96+
}
97+
process.exit(1);
98+
}
99+
}
100+
101+
main();

packages/docs/templates/README.md.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# {{PROJECT_NAME}}
22

3-
MCP documentation server powered by [@mcp-framework/docs](https://www.npmjs.com/package/@mcp-framework/docs).
3+
MCP documentation server powered by [@mcpframework/docs](https://www.npmjs.com/package/@mcpframework/docs).
44

55
## Setup
66

packages/docs/templates/index.ts.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DocsServer, FumadocsRemoteSource } from "@mcp-framework/docs";
1+
import { DocsServer, FumadocsRemoteSource } from "@mcpframework/docs";
22

33
const source = new FumadocsRemoteSource({
44
baseUrl: process.env.DOCS_BASE_URL || "https://docs.example.com",

packages/docs/templates/package.json.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"dev": "tsc --watch"
1414
},
1515
"dependencies": {
16-
"@mcp-framework/docs": "^0.1.0",
16+
"@mcpframework/docs": "^0.1.0",
1717
"mcp-framework": "^0.2.18",
1818
"@modelcontextprotocol/sdk": "^1.11.0"
1919
},

0 commit comments

Comments
 (0)