Skip to content

mcps.portel.dev API Contract

Overview

The NCP CLI now fetches provider information from mcps.portel.dev to enable dynamic, server-side provider registry management. This allows adding new providers without requiring CLI updates.

Base URL

https://mcps.portel.dev/api

Endpoints Required

1. List All Providers

Endpoint: GET /api/providers

Description: Returns all available MCP providers

Response:

json
{
  "canva": {
    "id": "canva",
    "name": "Canva",
    "description": "Design and creative tools",
    "website": "https://www.canva.com",
    "recommended": "stdio",
    "stdio": {
      "setup": {
        "description": "Authenticate with Canva CLI",
        "command": "npx @canva/cli@latest login",
        "needsSetup": true
      },
      "command": "npx",
      "args": ["-y", "@canva/cli@latest", "mcp"]
    },
    "http": {
      "url": "https://mcp.canva.com/mcp",
      "auth": "oauth",
      "docs": "https://www.canva.dev/docs/connect/mcp-server/",
      "notes": "Requires OAuth app registration. Stdio version recommended."
    }
  },
  "slack": {
    "id": "slack",
    "name": "Slack",
    ...
  }
}

Alternative Response Format (also supported):

json
{
  "providers": {
    "canva": {...},
    "slack": {...}
  }
}

2. Get Single Provider

Endpoint: GET /api/providers/{providerId}

Description: Returns details for a specific provider

Example: GET /api/providers/canva

Response:

json
{
  "id": "canva",
  "name": "Canva",
  "description": "Design and creative tools",
  "website": "https://www.canva.com",
  "recommended": "stdio",
  "stdio": {
    "setup": {
      "description": "Authenticate with Canva CLI",
      "command": "npx @canva/cli@latest login",
      "needsSetup": true
    },
    "command": "npx",
    "args": ["-y", "@canva/cli@latest", "mcp"]
  },
  "http": {
    "url": "https://mcp.canva.com/mcp",
    "auth": "oauth",
    "docs": "https://www.canva.dev/docs/connect/mcp-server/"
  }
}

Error Response (404):

json
{
  "error": "Provider not found",
  "providerId": "unknown"
}

3. Search Providers (Optional)

Endpoint: GET /api/providers/search?q={query}

Description: Search providers by name, description, or ID

Example: GET /api/providers/search?q=design

Response:

json
{
  "results": [
    {
      "id": "canva",
      "name": "Canva",
      "description": "Design and creative tools",
      ...
    },
    {
      "id": "figma",
      "name": "Figma",
      "description": "Collaborative design tool",
      ...
    }
  ],
  "query": "design",
  "count": 2
}

Provider Schema

Provider Object

typescript
interface Provider {
  id: string;                      // Unique identifier (lowercase)
  name: string;                    // Display name
  description: string;             // Short description
  website: string;                 // Provider's website
  recommended: 'stdio' | 'http';   // Recommended transport
  stdio?: ProviderStdioConfig;     // Stdio configuration (if available)
  http?: ProviderHttpConfig;       // HTTP configuration (if available)
}

Stdio Configuration

typescript
interface ProviderStdioConfig {
  setup?: {
    description: string;   // What the setup does
    command: string;       // Command to run (e.g., "npx @canva/cli@latest login")
    needsSetup: boolean;   // Whether setup is required
  };
  command: string;         // Main command (e.g., "npx")
  args: string[];          // Arguments (e.g., ["-y", "@canva/cli@latest", "mcp"])
}

HTTP Configuration

typescript
interface ProviderHttpConfig {
  url: string;                          // MCP endpoint URL
  auth: 'bearer' | 'oauth' | 'basic';  // Authentication type
  docs: string;                        // Documentation URL
  notes?: string;                      // Additional notes/warnings
}

Client Behavior

Request Flow

User: ncp add canva

1. Fetch: GET https://mcps.portel.dev/api/providers/canva

2. If successful → Use remote provider data

3. If failed (network error, timeout) → Use local fallback

4. Display provider info and guide user through setup

Timeouts

  • Connection timeout: 5 seconds
  • Read timeout: 5 seconds
  • On timeout → Use local cache/fallback

Caching

  • NCP caches registry in memory during execution
  • No persistent cache (always fetches fresh on new command)
  • Local providers.json serves as offline fallback

Headers

User-Agent: ncp-cli
Accept: application/json

Error Handling

Server Down

If mcps.portel.dev is unreachable:

  • NCP falls back to local providers.json
  • User sees: (Using local provider registry)
  • Everything continues to work

Provider Not Found

Remote:

json
{
  "error": "Provider not found",
  "providerId": "unknown"
}

Client behavior:

  • Try local fallback
  • If still not found → Treat as manual add
  • Show: Unknown provider 'unknown'. Using manual configuration.

Invalid Response

If server returns invalid JSON or unexpected format:

  • Log error (if debug mode)
  • Fall back to local registry
  • Continue operation

Implementation Guidelines for mcps.portel.dev

Performance

  • Response time: < 200ms for single provider lookup
  • Caching: Implement CDN caching (5-minute TTL recommended)
  • Compression: Enable gzip/brotli

Security

  • HTTPS only
  • CORS: Enable for ncp-cli User-Agent
  • Rate limiting: 100 req/min per IP (generous for CLI tool)

Availability

  • Target uptime: 99.9%
  • Graceful degradation: If server down, clients use local cache
  • Health endpoint: GET /health{"status": "ok"}

Data Management

Where providers come from:

  1. Your existing MCP discovery/submission system
  2. Manual curation by Portel team
  3. Community submissions (verified by Portel)

Update frequency:

  • Real-time: New providers available immediately
  • No CLI update required
  • Backward compatible: Old CLIs work with new providers

Integration with Existing Discovery System

Current Flow (Already Working):

User: ncp find "design"

Query: mcps.portel.dev/discover

Found: Canva MCP

Elicitation: Install? (y/n)

Auto-install

New Flow (With Provider Registry):

User: ncp add canva

Query: mcps.portel.dev/api/providers/canva

Get provider details (stdio config, auth setup, etc.)

Guide user through setup

Auto-install

Unified Backend

Both endpoints can share the same provider database:

  • /discover → Search/discovery API
  • /api/providers → Provider details API
  • Same data, different views

Example Provider Entries

Canva (Stdio + HTTP)

json
{
  "id": "canva",
  "name": "Canva",
  "description": "Design and creative tools",
  "website": "https://www.canva.com",
  "recommended": "stdio",
  "stdio": {
    "setup": {
      "description": "Authenticate with Canva CLI",
      "command": "npx @canva/cli@latest login",
      "needsSetup": true
    },
    "command": "npx",
    "args": ["-y", "@canva/cli@latest", "mcp"]
  },
  "http": {
    "url": "https://mcp.canva.com/mcp",
    "auth": "oauth",
    "docs": "https://www.canva.dev/docs/connect/mcp-server/",
    "notes": "Requires OAuth app registration. Stdio version recommended for easier setup."
  }
}

Notion (HTTP only)

json
{
  "id": "notion",
  "name": "Notion",
  "description": "Notes and documentation",
  "website": "https://notion.so",
  "recommended": "http",
  "http": {
    "url": "https://mcp.notion.so",
    "auth": "bearer",
    "docs": "https://developers.notion.com/docs/mcp",
    "notes": "Requires API key from Notion settings → Integrations → Create integration"
  }
}

Custom MCP (Community Submitted)

json
{
  "id": "my-custom-mcp",
  "name": "My Custom MCP",
  "description": "Custom integration for...",
  "website": "https://github.com/user/my-mcp",
  "recommended": "stdio",
  "stdio": {
    "command": "node",
    "args": ["/path/to/server.js"]
  }
}

Testing

Endpoint Tests

bash
# Test provider list
curl https://mcps.portel.dev/api/providers

# Test single provider
curl https://mcps.portel.dev/api/providers/canva

# Test not found
curl https://mcps.portel.dev/api/providers/nonexistent
# Should return 404

# Test search
curl "https://mcps.portel.dev/api/providers/search?q=design"

CLI Tests

bash
# Test with live server
ncp add canva

# Test with server down (use local fallback)
# Temporarily block mcps.portel.dev in /etc/hosts
ncp add canva  # Should still work using local cache

Deployment Checklist

Backend (mcps.portel.dev):

  • [ ] Implement /api/providers endpoint
  • [ ] Implement /api/providers/{id} endpoint
  • [ ] Add provider data (Canva, Slack, GitHub, Notion, Linear)
  • [ ] Enable CORS
  • [ ] Add rate limiting
  • [ ] Deploy to production
  • [ ] Test all endpoints

CLI (NCP):

  • [ ] Update to fetch from mcps.portel.dev
  • [ ] Test remote fetch
  • [ ] Test local fallback
  • [ ] Build and release
  • [ ] Update documentation

Benefits of This Architecture

Dynamic Updates: Add providers without CLI releases ✅ Centralized: Single source of truth ✅ Offline Support: Local fallback if server down ✅ Scalable: Can grow to hundreds of providers ✅ Community: Enable provider submissions ✅ Discovery: Integrate with existing ncp find system


Questions?

Contact: dev@portel.dev Docs: https://docs.portel.dev/api

Released under the Elastic License 2.0.