# Directory Structure ``` ├── .gitignore ├── package.json ├── pnpm-lock.yaml ├── README.md ├── src │ └── server.ts └── tsconfig.json ``` # Files -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- ``` node_modules/ build/ *.log .env* ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- ```markdown # Jina Reader MCP Server Fetch the content of a remote URL as Markdown with Jina Reader ``` -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- ```json { "compilerOptions": { "target": "ES2022", "module": "Node16", "moduleResolution": "Node16", "outDir": "./build", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules"] } ``` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- ```json { "name": "mcp-jina-reader", "version": "0.1.0", "description": "Fetch the content of a remote URL as Markdown with Jina Reader", "private": true, "type": "module", "files": [], "scripts": {}, "dependencies": { "litemcp": "^0.7.0", "zod": "^3.23.8" }, "devDependencies": { "@types/node": "^20.11.24", "prettier": "^3.4.1", "typescript": "^5.3.3" }, "packageManager": "[email protected]+sha512.c8180b3fbe4e4bca02c94234717896b5529740a6cbadf19fa78254270403ea2f27d4e1d46a08a0f56c89b63dc8ebfd3ee53326da720273794e6200fcf0d184ab" } ``` -------------------------------------------------------------------------------- /src/server.ts: -------------------------------------------------------------------------------- ```typescript import { LiteMCP } from "litemcp"; import { z } from "zod"; async function fetchWithJinaReader(url: string): Promise<string> { const apiKey = process.env.JINA_API_KEY; console.error(`Fetching ${url}`, apiKey ? "with API key" : "without API key"); const response = await fetch(`https://r.jina.ai/${url}`, { headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined, }); if (!response.ok) { throw new Error(`Failed to fetch ${url}: ${response.statusText}`); } return response.text(); } const server = new LiteMCP("mcp-jina-reader", "0.1.0"); server.addTool({ name: "fetch_url_content", description: "Fetch the content of a URL as Markdown.", parameters: z.object({ url: z.string().url(), }), execute(args) { return fetchWithJinaReader(args.url); }, }); server.addPrompt({ name: "fetch_url_content", description: "Fetch the content of a URL as Markdown.", arguments: [ { name: "url", description: "The URL to fetch the content of.", required: true, }, ], async load(args) { const content = await fetchWithJinaReader(args.url); return `Content of ${args.url}:\n${content}`; }, }); server.start(); ```