مواد پر جائیں

MCP API key and bearer token setup for each client

Get a free Quran Gallery key and send it as a bearer token from Claude Code, Cursor, VS Code, Gemini CLI or mcp-remote, then test it with one curl call.

یہ صفحہ ابھی ترجمہ نہیں ہوا — انگریزی نسخہ دکھایا جا رہا ہے۔

اس صفحے پر

A key is optional. Without one, every client in this section works on the keyless tier. A free key raises the limit and lifts the page-range caps. This page shows, for each client, where the key goes, how to test it, and what the two errors you are most likely to meet look like.

1. Get a free key

  1. Sign in at accounts.qurangallery.com (the Developers page; the server’s own GET answer links to the same address). Create an account if you have none.
  2. Create a key and give it a name you will recognise, such as laptop-claude-code.
  3. Copy the full key when it is shown. It is shown once; afterwards only its first characters are visible. Keys start with qg_sk_.

How keys are created, rotated and revoked is covered in API keys.

2. What a key changes

Without a keyWith a free key
Tool calls10 a minute and 200 a day, per IP address60 requests a minute, per key
shamela_read (unit: 'range')Up to 5 pages per callUp to 20
shamela_read (unit: 'section')Up to 10 pages per callUp to 100

The full table, with the RateLimit-* headers, is in Limits and errors.

3. Per-client setup

In every example, qg_sk_... stands for your own key. Do not paste the placeholder as it is: a key that is sent is always checked, so the placeholder is refused with a 401 (see what a 401 looks like). Where a client can read the key from an environment variable or ask for it, that is shown instead of a literal value.

The server URL is the same everywhere:

https://qurangallery.com/mcp/shamela

Claude Code

Set the key in your shell, then register the server with --header. The shell expands the variable, so the key is not typed into the command:

export QG_MCP_KEY='qg_sk_...'
claude mcp add --transport http quran-gallery 
  https://qurangallery.com/mcp/shamela 
  --header "Authorization: Bearer $QG_MCP_KEY"

claude mcp add stores the header value in the Claude Code configuration for the scope you chose, so that file now holds the key. Run claude mcp list to confirm the server shows as connected. To go back to keyless use, run claude mcp remove quran-gallery and add it again without --header.

Cursor

In ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project), add headers. Cursor resolves ${env:NAME} in headers, so the key can stay in an environment variable instead of the file:

{
	"mcpServers": {
		"quran-gallery": {
			"url": "https://qurangallery.com/mcp/shamela",
			"headers": { "Authorization": "Bearer ${env:QG_MCP_KEY}" }
		}
	}
}

Start Cursor from a shell where QG_MCP_KEY is set, or set it for your user account, then toggle the server off and on in Cursor’s MCP list. If the variable is not set when Cursor starts, the header is wrong and the server answers 401.

VS Code

Use an input, so VS Code asks for the key once and keeps it out of .vscode/mcp.json:

{
	"inputs": [
		{
			"type": "promptString",
			"id": "qg-key",
			"description": "Quran Gallery API key (qg_sk_...)",
			"password": true
		}
	],
	"servers": {
		"quran-gallery": {
			"type": "http",
			"url": "https://qurangallery.com/mcp/shamela",
			"headers": { "Authorization": "Bearer ${input:qg-key}" }
		}
	}
}

Start the server from the Start action above its entry. VS Code asks for the key on the first start. According to the same VS Code reference, a server that needs an interactive input like this one is not forwarded to Copilot harness sessions, so use it in VS Code chat (VS Code).

Gemini CLI

With the command, using --header (or -H):

gemini mcp add --transport http quran-gallery 
  https://qurangallery.com/mcp/shamela 
  --header "Authorization: Bearer qg_sk_..."

In settings.json, the streaming URL is httpUrl and the key goes in headers:

{
	"mcpServers": {
		"quran-gallery": {
			"httpUrl": "https://qurangallery.com/mcp/shamela",
			"headers": { "Authorization": "Bearer qg_sk_..." }
		}
	}
}

Gemini CLI writes settings.json in your project folder by default, or in ~/.gemini/ with --scope user. Either way the key is now in that file: keep it out of git (Gemini CLI).

mcp-remote (Claude Desktop and other clients that run local commands)

mcp-remote is a local bridge for clients that can start a program but cannot connect to a URL (Connect any MCP client). It takes the header as the argument after --header, and the value can read an environment variable:

{
	"mcpServers": {
		"quran-gallery": {
			"command": "npx",
			"args": [
				"-y",
				"mcp-remote",
				"https://qurangallery.com/mcp/shamela",
				"--header",
				"Authorization:${QG_AUTH}"
			],
			"env": { "QG_AUTH": "Bearer qg_sk_..." }
		}
	}
}

The space inside Bearer qg_sk_... sits in env rather than in args, because some clients mangle a space inside an argument. The mcp-remote README describes this for Cursor, Codex CLI and Claude Desktop on Windows. It needs Node.js.

4. Test a key with one call

Before blaming a client, send an initialize request yourself. Read the key into a shell variable first, so it does not end up in your history:

read -rs QG_MCP_KEY   # paste the key, press Enter

curl -s -i https://qurangallery.com/mcp/shamela 
  -H 'Content-Type: application/json' 
  -H 'Accept: application/json, text/event-stream' 
  -H "Authorization: Bearer $QG_MCP_KEY" 
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'

A valid key returns HTTP/2 200 and a JSON body whose serverInfo.name is qurangallery-shamela, with ratelimit-limit: 60 in the headers (the keyed limit). Run it once, not in a loop.

5. What the errors look like

What a 401 looks like

A key that is sent is always checked. A wrong, deleted or placeholder key is refused rather than treated as keyless. This is the real response to a placeholder key, read from the live endpoint on 2026-11-01:

HTTP/2 401
www-authenticate: Bearer realm="qurangallery-mcp", error="invalid_token"

{"jsonrpc":"2.0","id":null,"error":{"code":-32001,"message":"That API key is not valid."}}

Fix it by sending the real key, or by removing the Authorization header altogether. A header with nothing after Bearer, which is what an unset environment variable in a header template produces, gets the same 401.

What a 429 looks like

A rate limit gives HTTP 429, the JSON-RPC code -32004, and a retry-after header in seconds. The bodies below are quoted from the server code, not from a live trigger, because producing a 429 means spending the keyless allowance.

Keyless, the message names the limit and where to get a key:

{"jsonrpc":"2.0","id":null,"error":{"code":-32004,"message":"Keyless limit reached: 10 tool calls a minute per IP. A free API key raises it to 60 a minute: https://accounts.qurangallery.com/developers"}}

The daily limit says “200 tool calls a day” in place of the minute figure. With a key, the message is Rate limit exceeded. Wait for the retry-after seconds and try again. The other errors (403, 503) are in Limits and errors.

6. Key hygiene

  • Never commit a key. Keep it in your shell, a password manager or the client’s secret input (the VS Code inputs above), and keep any config file that holds a literal key out of git.
  • One key per machine or tool, named for it, so you can delete one without breaking the others.
  • If a key leaks, delete it first, then create a replacement. A deleted key can keep working for up to a minute because verified keys are cached (Limits and errors).
  • Never put a key in a URL. The server reads it only from Authorization: Bearer; a query parameter does nothing.
  • Do not paste a key into a chat. Your assistant does not need to see it; the client sends it.
اس صفحے کو GitHub پر ایڈٹ کریں