MCP logo

MCP

Organization
jina-ai

Official Jina AI Remote MCP Server

Publisherjina-ai
RepositoryMCP
LanguageTypeScript
Forks
94
Stars
866
Available tools
0
Transport typestdio, streamable-http
Categories
LicenseApache-2.0
Links
  • Connect tools to AI workflows

    MCP exposes MCP capabilities that can be used by compatible AI clients and agents.

  • 0 available tools

    Browse the callable actions below, including names and descriptions when provided by the server.

  • Ready-to-copy setup

    Use the installation snippets to configure this server in your preferred MCP client.

  • Open source signals

    866 stars and 94 forks from the linked repository.

Jina AI Remote MCP Server

A remote Model Context Protocol (MCP) server for the Jina Reader, Search, Embeddings and Reranker APIs:

Usage

[!WARNING] Some clients do not support env variable, so you may need to replace ${JINA_API_KEY} below to a hardcoded real API key jina_xxx.

For client that supports remote MCP server:

json
{
  "mcpServers": {
    "jina-mcp-server": {
      "url": "https://mcp.jina.ai/v1",
      "headers": {
        "Authorization": "Bearer ${JINA_API_KEY}" // optional
      }
    }
  }
}

For Claude Code:

bash
claude mcp add -s user --transport http jina https://mcp.jina.ai/v1 \
  --header "Authorization: Bearer ${JINA_API_KEY}"

For OpenAI Codex: find ~/.codex/config.toml and add the following:

toml
[mcp_servers.jina-mcp-server]
command = "npx"
args = [
    "-y",
    "mcp-remote",
    "https://mcp.jina.ai/v1",
    "--header",
    "Authorization: Bearer ${JINA_API_KEY}"]

For client that does not support remote MCP server yet, you need mcp-remote a local proxy to connect to the remote MCP server.

json
{
  "mcpServers": {
    "jina-mcp-server": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://mcp.jina.ai/v1",
        "--header",
        "Authorization: Bearer ${JINA_API_KEY}"
      ]
    }
  }
}

Available tools

ToolDescriptionIs Jina API Key Required?
primerGet current contextual information for localized, time-aware responsesNo
read_urlRead a web page or PDF as markdown. Pass question for passages instead of the full body via Reader APIOptional*
capture_screenshot_urlCapture a screenshot of a web page via Reader APIOptional*
guess_datetime_urlGuess a page's publish or last-update datetime, with a confidence scoreNo
search_webSearch the web. Returns titles, URLs and engine snippets via Reader APIYes
search_arxivSearch academic papers and preprints on arXiv repository via Reader APIYes
search_ssrnSearch academic papers on SSRN (Social Science Research Network) via Reader APIYes
search_imagesSearch the web for images via Reader APIYes
search_jina_blogSearch Jina AI news and blog posts at jina.ai/newsNo
sort_by_relevanceRerank documents by relevance to a query via Reranker APIYes
deduplicate_stringsGet top-k semantically unique strings via Embeddings API and submodular optimizationYes
extract_pdfExtract figures, tables, and equations from PDF documents (arXiv papers or any PDF URL) using layout detectionYes

Optional tools work without an API key at rate limits. Use a key for higher limits. Free keys: https://jina.ai

Tool Filtering before Registering

Registering a tool costs context tokens for its name, description and schema whether or not it is called. With 12 tools, that budget is spent before the first request.

Filtering server-side through query parameters on the endpoint URL (/v1?...) excludes tools before registration, so the client never sees them.

Query Parameters

ParameterDescriptionExample
exclude_toolsComma-separated tool names to excludeexclude_tools=search_web,search_arxiv
include_toolsComma-separated tool names to includeinclude_tools=read_url,search_web
exclude_tagsComma-separated tags to excludeexclude_tags=search,rerank
include_tagsComma-separated tags to includeinclude_tags=search,read
max_tokensCap read_url response size in tokens. 0 disables truncationmax_tokens=50000

Available Tags

TagTools
searchsearch_web, search_arxiv, search_ssrn, search_images, search_jina_blog
readread_url, capture_screenshot_url
utilityprimer, guess_datetime_url, extract_pdf
reranksort_by_relevance, deduplicate_strings

Precedence

Filters are applied in this order (highest to lowest priority):

  1. exclude_tools - Always excludes specified tools
  2. exclude_tags - Excludes tools in specified tags
  3. include_tools - Includes specified tools
  4. include_tags - Starts with only tools in specified tags

Examples

Exclude the rerank and utility tags:

json
{
  "mcpServers": {
    "jina-mcp-server": {
      "url": "https://mcp.jina.ai/v1?exclude_tags=rerank,utility",
      "headers": {
        "Authorization": "Bearer ${JINA_API_KEY}"
      }
    }
  }
}

Only include search and read tools:

json
{
  "mcpServers": {
    "jina-mcp-server": {
      "url": "https://mcp.jina.ai/v1?include_tags=search,read",
      "headers": {
        "Authorization": "Bearer ${JINA_API_KEY}"
      }
    }
  }
}

Exclude specific tools:

json
{
  "mcpServers": {
    "jina-mcp-server": {
      "url": "https://mcp.jina.ai/v1?exclude_tools=search_ssrn,search_images",
      "headers": {
        "Authorization": "Bearer ${JINA_API_KEY}"
      }
    }
  }
}

Troubleshooting

I got stuck in a tool calling loop - what happened?

This is a common issue with LMStudio when the default context window is 4096 and you're using a thinking model like gpt-oss-120b or qwen3-4b-thinking. As thinking and tool calling continue, the run hits the context limit, the model loses the start of the task, and it loops.

Load the model with enough context length to hold the whole tool-calling chain.

set long enough context

I can't see all tools.

Some MCP clients have local caching and do not actively update tool definitions. If tools are missing or look outdated, remove and re-add the jina-mcp-server to force a refresh of the cached definitions. In LMStudio, you can click the refresh button to load new tools.

update local mcp clients

Claude Desktop says "Server disconnected" on Windows

Cursor and Claude Desktop (Windows) have a bug where spaces inside args aren't escaped when it invokes npx, which ends up mangling these values. You can work around it using:

json
{
  // rest of config...
  "args": [
    "mcp-remote",
    "https://mcp.jina.ai/v1",
    "--header",
    "Authorization:${AUTH_HEADER}" // note no spaces around ':'
  ],
  "env": {
    "AUTH_HEADER": "Bearer <JINA_API_KEY>" // spaces OK in env vars
  }
},

Cursor shows a red dot on this MCP status

Likely a Cursor UI bug. The MCP works. Toggling off/on clears the dot; on a remote MCP that restarts the local proxy, not a server.

cursor shows red dot

My LLM never uses some tools

If all tools are enabled but the model still ignores some, that is expected: models call the tools they were trained on. Some research says LLMs must be trained to use a tool family. In Cursor, add this rule to a .mdc file:

text
---
alwaysApply: true
---

When you are uncertain about knowledge, or the user doubts your answer, always use Jina MCP tools to search and read best practices and latest information. Use search_arxiv and read_url together when questions relate to theoretical deep learning or algorithm details. Use search_ssrn for social sciences, economics, law, and finance research. search_web, search_arxiv, and search_ssrn cannot be used alone - always follow with read_url on the result URLs. One read_url call can take up to 5 URLs at once.

Why is my content truncated?

Claude Code, Claude Desktop, and Cursor enforce a fixed 25k token limit on MCP tool responses. To stop these clients from rejecting a large response outright, this server applies a token guardrail to read_url.

Items are kept whole, in order, while they fit. The first that does not fit is cut to a prefix that does, and later items are dropped. A [jina-mcp] ... note records what was truncated or omitted, so a partial document is marked partial. At least one item always survives, even one over budget.

The server targets below the limit. It counts tokens with cl100k, the client with its own tokenizer, the cut is a proportional character estimate, and the client measures the serialized JSON payload instead of the raw text. It therefore also enforces a ceiling of 3 bytes per allowed token, which holds across tokenizers for ASCII prose (~3.6 bytes/token) and CJK (~3 bytes/token). Cutting short loses part of the content. A rejected response loses all of it.

Any client can set its own budget with max_tokens on the endpoint URL (for example https://mcp.jina.ai/v1?max_tokens=50000), and max_tokens=0 disables truncation entirely. Clients with configurable limits, such as OpenAI Codex (tool_output_token_limit), are otherwise left alone.

Several queries or URLs in one call

search_web, search_arxiv, search_ssrn and read_url take a string or an array on query / url. An array runs every item concurrently in a single round trip. search_images takes one query at a time.

jsonc
{ "url": ["https://react.dev/reference/react/useState",
          "https://docs.python.org/3/library/functions.html"],
  "question": "what does the hook or built-in return" }

Arrays cap at 5 entries, enforced by the schema. withAllLinks, withAllImages, question, chunk_size, topk, ocr and page are set once for the whole array, not per entry: every URL in the call gets the same question, and a multi-page OCR needs one call per page.

Why is the endpoint called /sse but using Streamable HTTP?

The /sse endpoint URL is kept for backward compatibility with existing users. The recommended endpoint is now /v1. Both use the same Streamable HTTP transport (the new MCP standard from spec 2025-03-26), not the deprecated SSE transport.

This works because:

  • Claude Desktop, Cursor, Windsurf use mcp-remote which defaults to http-first strategy (tries Streamable HTTP first)
  • Claude Code has native support for both transports
  • LM Studio supports direct connection to Streamable HTTP endpoints

The response streaming still uses SSE format (Content-Type: text/event-stream), but the protocol layer (session management, initialization) follows Streamable HTTP spec. All major MCP clients are compatible.

Client-side tool filtering with mcp-remote

If you're using mcp-remote as a local proxy, you can also filter tools client-side using its --ignore-tool flag:

json
{
  "mcpServers": {
    "jina-mcp-server": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://mcp.jina.ai/v1",
        "--header",
        "Authorization: Bearer ${JINA_API_KEY}",
        "--ignore-tool", "search_images",
        "--ignore-tool", "search_ssrn",
        "--ignore-tool", "extract_pdf"
      ]
    }
  }
}

This filters at the proxy level before tools reach the client. Server-side filtering via query parameters (see Tool Filtering) is cheaper, because the tokens are never sent.

Reading a page with a question in mind

read_url returns the whole page. Pass question and the page is chunked, its passages are scored against the query by Reranker v3.5, and only the highest-scoring ones are returned.

ParameterDefaultEffect
question(unset)Unset returns the full page. Set returns passages instead of content.
chunk_size100Target passage size in words, split at sentence boundaries, so a target, not a hard cut. Counted in words in every script. 1-4096.
topk1Passages to keep, best first. 1-50.

question gates the other two. Without it the response is unchanged from a plain read.

jsonc
// full page: 69,530 bytes
{ "url": "https://www.paulgraham.com/greatwork.html" }

// passages: 1,195 bytes
{ "url": "https://www.paulgraham.com/greatwork.html",
  "question": "Why are new ideas hard to see?", "topk": 3, "chunk_size": 50 }

Response shape: question, snippets, snippet_source: content, no content. snippets is one element holding up to topk passages joined by …. No score is returned, so relevance cannot be thresholded here. Ladder measured at chunk_size=40: topk 1 gives 433 bytes and no separator, 2 gives 699 bytes and one separator, 5 gives 1,537 bytes and one separator. Fewer than topk passages can come back.

If extraction cannot run — empty page, unreadable page, no API key to rank with — the full body comes back with snippet_source: full_content and a note.

Byte cost, same URL, same endpoint, bytes of returned text:

pageplain readwith question
docs.python.org/3/library/functions.html83,786874
en.wikipedia.org/wiki/List_of_countries_by_GDP_(nominal)12,295912
paulgraham.com/greatwork.html69,5301,195

Measured against a local wrangler dev of this repo with an API key. r.jina.ai returns different sizes for the same URL, so do not mix the two sets.

Verified on this build: Python docs, Chinese Wikipedia, React references, GitHub READMEs, arXiv PDFs, essays. Compound questions worked here too (the os.path query returned both the join rule and the splitext example, and Beijing returned both population and area), so ask one thing per call as a habit, not because every multi-part question fails.

Reproduced failure modes. The response does not flag any of these:

  • Positional questions fail. Ranking matches text, not document order. raw.githubusercontent.com/vitejs/vite/main/packages/vite/CHANGELOG.md is 283,749 bytes and opens with ## [8.3.0] ... (2026-09-10). Asked for the latest released version, it returned 1,008 bytes containing 6.0.0 and no 8.3.0 at all. Read the first screen for latest, first, current.
  • Tables, fenced code and page furniture are removed before ranking. read.ts says so and it holds: the GDP list page is 12,295 bytes through read_url and contains Japan but not 4,379,253. Asked for Japan's figure, question returned the map colour legend, $1–5 trillion $750 billion – $1 trillion …. A number that lives in a table is not reachable this way.
  • Inline code loses tokens. curl -fsSL https://bun.sh/install | bash came back as curl -fsSL | bash. Never run a command copied out of a passage without checking the source.
  • Blocked pages return their login wall as content. x.com/jina_ai returned 315 bytes of Log inSign up … hasn't posted with snippet_source: content and no error.
  • chunk_size is not monotonic. 50 returned 521 bytes opening on the answer (And yet empirically having new ideas is hard.); 400 returned 2,260 bytes opening off-topic (But the relationship is closer than that.). Use 40-70 for commands, signatures and numbers, 150-200 for explanation.

A question-grounded read gets a 60s budget against 30s for a plain read, because chunking and reranking run after the fetch. The same 60s applies to a URL array carrying a question.

Reading a scanned document or a PDF

A plain read parses HTML. It returns nothing useful when the text is not in the markup (scanned pages, image-only PDFs), and flattens formulas and table structure otherwise. Pass ocr and the rendered page goes through jina-ocr-v1 as an image, returning Markdown with formulas and tables intact.

jsonc
{ "url": "https://arxiv.org/pdf/2609.03181", "ocr": true }            // page 1
{ "url": "https://arxiv.org/pdf/2609.03181", "ocr": true, "page": 2 } // page 2

One page per call. Page 1 unless page says otherwise, so a long document needs one call per page. Measured on arXiv 2609.03181, a 20-page paper:

bytes returnedtokens billed
plain read49,466 (whole PDF)13,864
ocr: true2,963 (page 1)61,520
ocr: true, page: 22,749 (page 2)62,720

Off by default, because OCR bills more tokens per page than a plain read costs per document. Turn it on when the HTML path fails or the layout matters. page is shared across a URL array, so several pages of one document take one call each.

Functions have been removed in v1.10.0

The following tools has been proved not effective or simply broken.

ToolUse instead
search_web_deepsearch_web, then read_url with question on the pages you pick
parallel_search_web, parallel_search_arxiv, parallel_search_ssrn, parallel_read_urlpass an array to query / url on the singletons
expand_queryrewrite the query yourself; the endpoint returned one near-copy of the input
classify_textclassify with the model; label scores differed by ~0.006, which is noise
deduplicate_imagesthe response carried base64 JPEG data, not just the selected items
search_bibtexread the citation from the publisher or DBLP page directly; both backends were failing live
show_api_keynothing. It returned the bearer token into the conversation

Developer Guide

Local Development

bash
# Clone the repository
git clone https://github.com/jina-ai/MCP.git
cd MCP

# Install dependencies
npm install

# Start development server
npm run start

Deploy to Cloudflare Workers

Deploy to Workers

This will deploy your MCP server to a URL like: jina-mcp-server.<your-account>.workers.dev/v1

Installation

TypingMind
{
  "mcpServers": {
    "jina-ai-mcp": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://mcp.jina.ai/sse",
        "--header",
        "Authorization: Bearer ${JINA_API_KEY}"
      ]
    }
  }
}

Use MCP MCP with multiple AI models

TypingMind connects MCP tools at the workspace level, so once MCP is connected, you can use it with different AI models in TypingMind instead of setting it up separately for each model. You can run MCP locally on your device or connect to a remote MCP server URL.

Option 1: Use the local connector

Use this when the MCP server needs access to local files, apps, or private resources on your computer.

1

Open the MCP settings

In TypingMind, go to Settings, Advanced Settings, then Model Context Protocol and choose Setup Connector.

  1. Open TypingMind in your browser.
  2. Click the Settings icon.
  3. Go to Advanced Settings.
  4. Open the Model Context Protocol section.
  5. Click Setup Connector and choose This Device.
TypingMind MCP connector setup screen with This Device selected
2

Run the connector command

Choose This Device, copy the command from TypingMind, and run it in Terminal. Keep the process running while you use MCP.

  1. Copy the setup command shown by TypingMind.
  2. Open Terminal on macOS or Windows Terminal on Windows.
  3. Paste and run the command.
  4. Approve the package install if Terminal asks you to proceed.
  5. Keep the Terminal window running while using MCP tools.
3

Add MCP as a server

When the connector status is Ready, click Edit Servers and paste the MCP server configuration.

  1. Wait until the connector status shows Ready.
  2. Click Edit Servers.
  3. Paste the MCP MCP server configuration.
  4. Save the server list.
  5. Refresh if you want to confirm the connector is still ready.
TypingMind MCP settings showing active server and Edit Servers button
{
  "mcpServers": {
    "jina-ai-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "jina-mcp"
      ]
    }
  }
}
4

Use it across models

Save the server list, open Plugins, enable the MCP MCP tools, then select any supported AI model in TypingMind and use the tools in chat or assign them to an AI agent.

  1. Open the Plugins page in TypingMind.
  2. Enable the MCP MCP tools.
  3. Start a chat and choose the AI model you want to use.
  4. Use the MCP tools in chat or assign them to an AI agent.
  5. Switch to another AI model whenever needed without reconnecting MCP.
TypingMind chat using enabled MCP tools with a selected AI model
Can you use MCP to help me with this task?
MCP
Sure. I read it.
Here is what I found using MCP.

Option 2: Add an MCP server URL

Use this when MCP is already hosted remotely or your team wants one shared connector that multiple users can access.

1

Open MCP connectors

In TypingMind, go to Plugins, open MCP connectors, then choose Add URL.

  1. Open TypingMind in your browser.
  2. Go to Plugins.
  3. Open MCP connectors.
  4. Click Add URL.
TypingMind Add Custom MCP Server URL form
2

Paste the server URL

Enter https://mcp.jina.ai/sse in the Server URL field. Add a connection name, description, icon, custom HTTP headers, or OAuth client settings if the server requires them.

  1. Paste https://mcp.jina.ai/sse into the Server URL field.
  2. Enter a connection name for MCP.
  3. Add a description and icon if you want it to be easier to identify.
  4. Add custom HTTP headers or OAuth client details if the server requires authentication.
3

Create the connection

Click Create connection, then return to the Plugins list and confirm the new MCP connection is active.

  1. Click Create connection.
  2. Return to the MCP connectors list.
  3. Confirm the MCP connection appears as active.
  4. Refresh the plugin list if the connection does not appear immediately.
4

Switch models without reconnecting

Start a chat with your preferred model, enable the MCP tools from Plugins, and switch to another model whenever needed. The MCP connection stays available to the TypingMind workspace.

  1. Start a new chat in TypingMind.
  2. Select the AI model you want to use.
  3. Enable the MCP tools from Plugins.
  4. Ask the model to use the tool when needed.
  5. Switch to another AI model and reuse the same MCP connection.
TypingMind chat using enabled MCP tools with a selected AI model
Can you use MCP to help me with this task?
MCP
Sure. I read it.
Here is what I found using MCP.

Frequently asked questions

What is the MCP MCP server used for?

MCP is an MCP server that lets compatible AI clients connect to external tools and context. In TypingMind, you can add this MCP server once and make its tools available in your AI workspace.

Can I use MCP MCP with multiple AI models in TypingMind?

Yes. TypingMind connects MCP tools at the workspace level, so you can use MCP with different AI models such as Claude, ChatGPT, Gemini, or other models you have configured in TypingMind without setting up the MCP server separately for each model.

Why use MCP MCP with TypingMind?

TypingMind is one of the best frontends for LLM chat because it brings multiple AI models, prompts, plugins, AI agents, API keys, and MCP tools into one workspace. With MCP connected, you can use its MCP tools across your preferred models while keeping your chat workflow organized in TypingMind.

How do I connect MCP MCP to TypingMind?

MCP can be connected in TypingMind with the local MCP connector or by adding a remote MCP server URL. Use the local connector when the server needs access to files, apps, or private resources on your device, and use a server URL when the MCP server is hosted remotely.

What tools does MCP MCP provide in TypingMind?

MCP exposes MCP capabilities that can be enabled from the TypingMind Plugins page and used in chat or assigned to AI agents.

Do I need to share my API keys with TypingMind to use MCP MCP?

No. TypingMind is local-first and lets you keep your model providers, API keys, prompts, and MCP configuration under your control. If MCP requires authentication, add the required headers, OAuth settings, or local configuration for that MCP server when you create the connection.

Related MCP Servers

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇