Skip to content

DeepLinkNow MCP server for coding agents

Overview

@deeplinknow/mcp is an MCP server for coding agents such as Claude Code, Cursor, Claude Desktop, VS Code and Windsurf. With it installed, the agent can read DeepLinkNow's current docs, check your link domain and plan a migration while it writes the integration, instead of working from memory.

It covers iOS, Android, React Native, Expo and Flutter apps. Like DeepLinkNow itself, it does deep linking only: it never adds attribution, ad tracking or advertising IDs to your app.

The server runs on your machine over stdio and needs Node.js 20 or later. The source is MIT licensed: github.com/deeplinknow/dln-mcp.

Install

One-click install

No account or key needed. The docs, setup and domain-check tools work straight away.

Nothing happens? Open the Cursor or VS Code web link instead.

Claude Code

claude mcp add deeplinknow -- npx -y @deeplinknow/mcp

With your private key, for the two link tools:

claude mcp add deeplinknow --scope user --env DEEPLINKNOW_API_KEY=YOUR_PRIVATE_KEY -- npx -y @deeplinknow/mcp

Try it

Once it's installed, ask your agent:

  • Use DeepLinkNow to add deferred deep linking to this Expo app. Our link domain is myapp.deeplinknow.com.(get_setup_guide)
  • Check whether links.example.com's AASA and assetlinks.json files are set up correctly.(check_domain)
  • We use Firebase Dynamic Links. Plan our move to DeepLinkNow for this app.(migrate_from)
  • A DeepLinkNow match came back MEDIUM with a score of 58. Should we route it?(explain_match_result)
  • Search the DeepLinkNow docs: how do I test a deferred deep link on Android?(search_docs)

The one-click links and the commands above install the server without a key. To add the private key for the link tools, use the per-client configs below.

Claude Code

claude mcp add deeplinknow -- npx -y @deeplinknow/mcp

With the link tools (--scope user keeps the key out of the project's .mcp.json):

claude mcp add deeplinknow --scope user --env DEEPLINKNOW_API_KEY=YOUR_PRIVATE_KEY -- npx -y @deeplinknow/mcp

Cursor

Add to .cursor/mcp.json in the project, or ~/.cursor/mcp.json for every project:

{ "mcpServers": { "deeplinknow": { "command": "npx", "args": ["-y", "@deeplinknow/mcp"], "env": { "DEEPLINKNOW_API_KEY": "${env:DEEPLINKNOW_API_KEY}" } } } }

Leave out env if you don't need the link tools.

Claude Desktop

Open Settings → Developer → Edit Config, which opens claude_desktop_config.json (~/Library/Application Support/Claude/ on macOS, %APPDATA%\Claude\ on Windows), and add:

{ "mcpServers": { "deeplinknow": { "command": "npx", "args": ["-y", "@deeplinknow/mcp"] } } }

Restart Claude Desktop. To use the link tools, add "env": { "DEEPLINKNOW_API_KEY": "YOUR_PRIVATE_KEY" } next to args.

VS Code

Add to .vscode/mcp.json. VS Code asks for the key once and stores it securely:

{ "inputs": [ { "type": "promptString", "id": "deeplinknow-api-key", "description": "DeepLinkNow private API key (dln_priv_…), only for list_links and create_link. Leave empty otherwise.", "password": true } ], "servers": { "deeplinknow": { "type": "stdio", "command": "npx", "args": ["-y", "@deeplinknow/mcp"], "env": { "DEEPLINKNOW_API_KEY": "${input:deeplinknow-api-key}" } } } }

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

{ "mcpServers": { "deeplinknow": { "command": "npx", "args": ["-y", "@deeplinknow/mcp"], "env": { "DEEPLINKNOW_API_KEY": "YOUR_PRIVATE_KEY" } } } }

Leave out env if you don't need the link tools.

Other clients

Any MCP client that runs stdio servers: command npx, arguments -y @deeplinknow/mcp.

What to ask

Add DeepLinkNow deferred deep linking to this app. Our link domain is myapp.deeplinknow.com.

The agent reads the setup guide for your platform, installs the SDK, adds the Associated Domains entitlement and the Android intent filter, calls checkDeferredDeepLink() on launch and routes the result through your router. Then it checks your domain.

Other requests it handles:

  • "Check myapp.deeplinknow.com" (or your custom domain). It validates apple-app-site-association against Apple's CDN copy and assetlinks.json against Google's Digital Asset Links API, and looks the domain up on the EasyPrivacy and AdGuard block lists. It works for any domain, including the one you use today.
  • "We're on Firebase Dynamic Links. Move us to DeepLinkNow." Branch, AppsFlyer and Adjust work too. You get a plan and a code diff for your platform. If you use one of those for attribution, the plan keeps it for that and moves only the deep links.
  • "This match came back MEDIUM with a score of 58. Should we route it?" The agent explains each part of the score and what a minConfidence of 50 or 75 would do. The threshold stays your decision.

Tools

| Tool | Needs a key | What it does | |---|---|---| | get_setup_guide | No | Setup steps and code for ios, android, react-native, expo or flutter, from these docs (a bundled copy when offline) | | search_docs | No | Searches the full DeepLinkNow docs and returns the matching sections with links | | check_domain | No | Checks a domain's apple-app-site-association (and Apple's CDN copy), assetlinks.json (and Google's verdict), and whether the domain or its CNAME chain is on the EasyPrivacy or AdGuard block lists | | explain_match_result | No | Explains a fingerprint match's confidence_score and match_quality, and how to choose minConfidence | | migrate_from | No | A migration plan and code diff from firebase-dynamic-links, branch, appsflyer or adjust | | list_links | Private key, paid plan | Lists the app's links (dashboard, API and on-demand), with search and paging | | create_link | Private key, paid plan | Creates a link with a custom path, link-page text, social preview, metadata or campaign |

It also exposes deeplinknow://llms.txt and deeplinknow://docs/{page} as resources, and two prompts: add_deferred_deep_linking and migrate_to_deeplinknow.

The first check_domain run downloads the block lists (about 22 MB). Later checks in the same session reuse them for a day.

Keys

You don't need an account or a key for the first five tools.

list_links and create_link call the management API, which needs your app's private key (dln_priv_…, from the app's API Keys page in the dashboard) as DEEPLINKNOW_API_KEY. The management API is on paid plans (pricing). A private key acts on one app.

You never have to create links: any path on your link domain already works. The link tools are for listing links, or for creating one with a custom preview or campaign.

The private key stays in your MCP config. Your app only ever contains the public key (dln_pub_…). The server refuses a public key for the link tools without sending it, and it never prints, logs or returns the private key: it sends it only in the x-api-key header to the DeepLinkNow API.

| Variable | Default | Meaning | |---|---|---| | DEEPLINKNOW_API_KEY | unset | Your app's private key, only for list_links and create_link | | DEEPLINKNOW_API_URL | https://deeplinknow.com | API base URL. Must be https (http only for localhost) |

What it doesn't do

  • It never writes files or runs commands. The server only returns text to the agent. Your agent makes the code changes, through its own tools and permission prompts.
  • It stores nothing on disk. Docs, block lists and check results are cached in memory while the server runs (docs for an hour, block lists for a day, domain results for 5 minutes).
  • No telemetry. It collects no usage data.
  • It sends nothing about your code. get_setup_guide, search_docs, migrate_from and the resources fetch public docs from https://deeplinknow.com. check_domain fetches only the domain you name (over https, refusing private and local addresses), Apple's CDN, Google's Digital Asset Links API and the four public block lists. explain_match_result makes no requests. Only the link tools send your key and the link fields, to the DeepLinkNow API.

Keep agents on track

Paste this into your repo's AGENTS.md or CLAUDE.md so every session follows the same rules:

## Deep linking: DeepLinkNow - Link domain: myapp.deeplinknow.com. Any path and query on it is a deep link; nothing has to be created first. - The app contains only the public key (dln_pub_…). Never commit or ship the private key. - Initialize once at launch. Call checkDeferredDeepLink() once on launch and route to link.path with link.queryParams. Send links that open the installed app through the SDK's parse method and the same router. - Fingerprint matches are scored (confidenceScore, matchQuality). minConfidence is off by default; decide how to treat MEDIUM and LOW. - Use the DeepLinkNow MCP tools (get_setup_guide, check_domain, search_docs) instead of guessing.

Support