Why MCP Needs a Manifest: Solving the Configuration Chaos

Why MCP Needs a Manifest: Solving the Configuration Chaos

From manual JSON copy-pasting to one-click installation—how mcp-manifest.json brings autodiscovery to the MCP ecosystem.

David H. Friedel Jr.· 2026-04-01 ·MCP mcp-manifest specification

Introduction: The Current State of MCP Installation

If you've ever tried to install an MCP (Model Context Protocol) server, you know the drill. You find a promising tool in a GitHub repo, scroll down to the README, and encounter a wall of installation instructions. First, there's the package manager command—maybe it's npm install -g, or pip install, or dotnet tool install. Then comes the configuration: a JSON blob you need to manually copy into your MCP client's settings file. Don't forget to substitute the placeholder values with your actual API keys, file paths, or environment variables.

Every server has its own unique setup ritual. Some use environment variables. Others expect CLI arguments. A few require config files in specific locations. And the transport layer? That could be stdio, SSE, or streamable HTTP—information buried somewhere in the documentation.

This is the configuration chaos that mcp-manifest.json was built to solve.

The MCP protocol itself is elegant and well-designed. It defines a clear handshake between clients and servers, standardizing how they communicate once connected. But it's deliberately agnostic about everything that happens before that connection: installation, configuration, and client wiring. This gap forces every user to manually translate README instructions into client-specific configuration—a process that's error-prone, time-consuming, and a barrier to adoption.

What if installing an MCP server could be as simple as typing a domain name?

The Snowflake Problem: Every Server is Different

The MCP ecosystem is in its "curl the install script" era—every server is a snowflake installation with its own unique setup ritual.

Let's look at three real examples:

SQLite Explorer (npm-based):

npm install -g @anthropic/mcp-server-sqlite

Then add this to your Claude Desktop config:

{
  "mcpServers": {
    "sqlite": {
      "command": "mcp-server-sqlite",
      "args": ["/path/to/your/database.db"]
    }
  }
}

GitHub Integration (npm-based with secrets):

npm install -g @anthropic/mcp-server-github

Config requires an environment variable:

{
  "mcpServers": {
    "github": {
      "command": "mcp-server-github",
      "env": {
        "GITHUB_TOKEN": "ghp_your_token_here"
      }
    }
  }
}

IronLicensing (dotnet tool with custom registry):

dotnet tool install -g IronLicensing.Mcp \
  --add-source https://git.marketally.com/api/packages/ironservices/nuget/index.json

Config uses CLI arguments:

{
  "mcpServers": {
    "ironlicensing": {
      "command": "ironlicensing-mcp",
      "args": ["--profile", "production", "--api-key", "sk_live_xxx"]
    }
  }
}

Notice the pattern? Every server has:

  • Different installation methods (npm, pip, dotnet, cargo, Docker, binary downloads)
  • Different configuration mechanisms (env vars, CLI args, config files)
  • Different required parameters (API keys, file paths, URLs)
  • Different JSON structures for client configuration

This variability isn't a flaw in any individual server—it's the natural result of MCP's flexibility. But it creates friction for users and makes it impossible for clients to automate setup.

The snowflake problem means that every README becomes a custom installation guide, and every user becomes a manual translator between documentation and configuration files.

What the MCP Protocol Doesn't Cover

The MCP protocol is intentionally minimal. It defines:

The initialization handshake (initialize request/response)
Message formats (JSON-RPC 2.0)
Capability negotiation (what tools/resources/prompts are available)
Transport abstractions (stdio, SSE, HTTP streaming)

But it explicitly does not define:

How to install the server (package managers, dependencies, binaries)
How to configure the server (API keys, file paths, connection strings)
How to wire the client (what command to run, what arguments to pass)
How to discover servers (finding available MCP tools)

This is by design. MCP is a protocol, not a platform. It doesn't want to dictate installation methods or configuration formats. But this creates a standardization gap at the integration layer.

The MCP protocol defines the handshake after connection, but is agnostic about everything upstream: how to get the server running and how to wire a client to it.

This gap is where mcp-manifest.json lives. It's not a replacement for the MCP protocol—it's a companion specification that fills in the missing piece: machine-readable metadata about installation and configuration.

Think of it like this:

  • MCP protocol = the language servers and clients speak once connected
  • mcp-manifest.json = the instruction manual for getting them connected in the first place

The manifest format is deliberately minimal and static—just JSON, no code execution, no scripting. It describes:

  1. Server metadata (name, description, version, author)
  2. Installation methods (npm, pip, dotnet, cargo, Docker, binary)
  3. Configuration parameters (typed, with prompts and defaults)
  4. Transport details (stdio, SSE, HTTP)
  5. Client wiring template (the exact JSON to add to settings)

With this information, MCP clients can automate what users currently do manually.

The Vision: From Domain Name to Connected Server

Here's the vision: type a domain name, get a working MCP server.

No README hunting. No JSON copy-pasting. No guessing at configuration formats. Just:

User types: ironlicensing.com
↓
Client discovers manifest
↓
Client checks if tool is installed
↓
Client prompts for API key
↓
Client writes config
↓
Server connected ✓

This is enabled by autodiscovery—the same pattern that powers RSS feeds, OpenID, and webfinger. Server authors publish a pointer to their manifest, and clients resolve it automatically.

Autodiscovery Methods

1. Well-Known URL (preferred for APIs and headless services):

GET https://ironlicensing.com/.well-known/mcp-manifest.json

2. HTML Link Tag (for websites):

<link rel="mcp-manifest" 
      type="application/json" 
      href="/.well-known/mcp-manifest.json" />

Clients follow this resolution algorithm:

1. If input is a local file path → parse directly
2. If input ends with .json → fetch as manifest URL
3. Try well-known URL: {domain}/.well-known/mcp-manifest.json
4. Fetch HTML page, look for <link rel="mcp-manifest">
5. If found → fetch and parse manifest
6. Otherwise → discovery failed

Example: Full Installation Flow

A developer wants to add the IronLicensing MCP server. They type ironlicensing.com into their MCP client:

  1. Client tries https://ironlicensing.com/.well-known/mcp-manifest.json200 OK
  2. Parses the manifest:
    {
      "server": { "name": "ironlicensing", "displayName": "IronLicensing" },
      "install": [{
        "method": "dotnet-tool",
        "package": "IronLicensing.Mcp",
        "command": "ironlicensing-mcp"
      }],
      "config": [
        { "key": "api-key", "type": "secret", "prompt": "API key (sk_live_xxx)" }
      ]
    }
    
  3. Checks if ironlicensing-mcp is on PATH → not found
  4. Shows prompt: "Install IronLicensing MCP? Run: dotnet tool install -g IronLicensing.Mcp"
  5. User confirms → tool installed
  6. Prompts for config: "API key (sk_live_xxx)" → user enters key
  7. Writes to ~/.claude/settings.json:
    {
      "mcpServers": {
        "ironlicensing": {
          "command": "ironlicensing-mcp",
          "args": ["--api-key", "sk_live_xxx"]
        }
      }
    }
    
  8. Verifies MCP handshake → success

Total user effort: type domain name, enter API key. Everything else is automated.

No Central Registry Required

Unlike package managers, mcp-manifest.json doesn't require a central registry. Discovery is decentralized—each server author publishes their own manifest, and clients resolve it directly from the source.

This means:

  • No gatekeepers or approval processes
  • No single point of failure
  • Server authors control their own metadata
  • Manifests can be updated instantly

Optional registries could exist (crawling and indexing manifests for search/browsing), but they're not required for the core autodiscovery flow.

Real-World Impact: Before and After Examples

Let's compare the user experience before and after manifest support.

Before: Manual Installation (SQLite Explorer)

User journey:

  1. Google "MCP SQLite server"
  2. Find GitHub repo, open README
  3. Read installation instructions
  4. Run: npm install -g @anthropic/mcp-server-sqlite
  5. Scroll to configuration section
  6. Copy JSON blob from README
  7. Open ~/.claude/settings.json in editor
  8. Paste JSON into mcpServers object
  9. Edit placeholder path: "/path/to/database.db""/Users/me/project/data.db"
  10. Save file, restart Claude Desktop
  11. Test connection, debug if it fails

Time: 5-10 minutes
Error potential: High (typos in JSON, wrong path format, missing quotes)


After: Manifest-Based Installation (SQLite Explorer)

User journey:

  1. In Claude Desktop: "Add MCP Server"
  2. Type: sqlite.mcp-servers.dev
  3. Manifest discovered automatically
  4. Client shows: "SQLite Explorer — Query and explore SQLite databases"
  5. Prompt: "Database file path" → user browses to /Users/me/project/data.db
  6. Client installs tool (if needed), writes config, connects
  7. Server ready

Time: 30 seconds
Error potential: Low (typed inputs, validated paths, automated config generation)


Before: Multi-Step Setup (GitHub Integration)

User journey:

  1. Find GitHub MCP server repo
  2. Read: "You need a personal access token with repo scope"
  3. Open GitHub → Settings → Developer settings → Personal access tokens
  4. Generate token, copy to clipboard
  5. Return to README, copy config JSON
  6. Open settings file, paste JSON
  7. Find "GITHUB_TOKEN": "your-token-here"
  8. Paste token (hope it doesn't end up in git history)
  9. Save, restart client
  10. Test, debug if token has wrong scopes

Time: 10-15 minutes
Error potential: High (token scopes, JSON syntax, secret exposure)


After: Manifest-Based Setup (GitHub Integration)

User journey:

  1. Add server: github.com
  2. Manifest discovered
  3. Client shows: "GitHub API integration — manage repos, issues, PRs"
  4. Prompt: "GitHub personal access token (ghp_...)" → user pastes token
  5. Client marks field as secret (masked display, secure storage)
  6. Config written, server connected

Time: 1 minute
Error potential: Low (secret handling built-in, no manual JSON editing)


The Compound Effect

For a user setting up 5 MCP servers:

  • Before: 30-50 minutes, high frustration, multiple troubleshooting cycles
  • After: 5-10 minutes, low friction, consistent experience

For server authors, the benefits are even clearer:

  • Before: Every user support request involves debugging manual config
  • After: Clients validate config automatically, errors are caught early

Before: README must document every client's config format
After: One manifest works with all clients

Before: Users abandon setup if README is unclear
After: Autodiscovery reduces drop-off rate

Conclusion: Building a Better Developer Experience

The mcp-manifest.json specification isn't trying to replace the MCP protocol—it's completing it. MCP defines the conversation between clients and servers; the manifest defines how to start that conversation in the first place.

This matters because developer experience is a competitive advantage. The easier it is to install and configure MCP servers, the more developers will adopt them. The more developers adopt them, the richer the MCP ecosystem becomes.

Right now, MCP is powerful but fragmented. Every server is a bespoke installation. Every README is a custom guide. Every user is a manual translator. This friction is holding back adoption.

mcp-manifest.json offers a path forward:

Autodiscovery — like RSS feeds, discoverable from domain names
Any runtime — npm, pip, dotnet, cargo, Docker, binaries
Typed config — secrets, paths, URLs validated automatically
Zero-config clients — install, configure, and connect in one flow
Decentralized — no registry gatekeepers, no single point of failure

The format is minimal by design. A complete manifest can be as short as 10 lines:

{
  "$schema": "https://mcp-manifest.dev/schema/v0.1.json",
  "version": "0.1",
  "server": {
    "name": "my-server",
    "displayName": "My Server",
    "description": "What it does",
    "version": "1.0.0"
  },
  "install": [{
    "method": "npm",
    "package": "my-mcp-server",
    "command": "my-mcp-server",
    "priority": 0
  }],
  "transport": "stdio"
}

That's it. Ship this file, add a <link> tag to your website, and any MCP client can set up your server automatically.

What's Next?

The spec is at v0.1 — Draft. It's functional and has a reference implementation, but it needs feedback from the community:

  • Server authors: Does the manifest format cover your use case? What's missing?
  • Client developers: Is the discovery algorithm practical? What edge cases need handling?
  • Users: Does this solve the installation pain points you've experienced?

The goal is to build consensus around a standard that works for everyone—then bake it into the MCP ecosystem as a best practice.

Imagine a future where:

  • Every MCP server ships with a manifest
  • Every MCP client supports autodiscovery
  • Installing a new tool is as simple as typing a domain name

That future is within reach. The manifest format is the missing piece.

Let's solve the configuration chaos—together.

Back to Blog