---
title: Connection Proxy Endpoint
description: Connect MCP clients directly to upstream MCP servers through deco Studio
icon: Network
---

import Callout from "../../../../../components/ui/Callout.astro";

## Overview

The **Connection Proxy** endpoint enables MCP clients (like Cursor, Claude Desktop, or custom applications) to connect directly to a specific upstream MCP server through deco Studio. This endpoint acts as a secure, observable proxy that handles authentication, authorization, credential management, and monitoring.

## Endpoint

The canonical path is org-scoped:

```
POST https://your-studio-instance.com/api/:org/mcp/:connectionId
```

<Callout type="warning">
  The legacy unscoped form `POST /mcp/:connectionId` still works but emits a deprecation log on every request and will be removed. Update clients to the `/api/:org/...` path.
</Callout>

### Path Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `org` | `string` | Required | Organization slug — immutable for the lifetime of the org |
| `connectionId` | `string` (UUID) | Required | The unique identifier of the connection to proxy requests to |

## Authentication

The Connection Proxy requires authentication using one of:

- **OAuth Bearer Token**: `Authorization: Bearer <token>`
- **API Key**: `Authorization: Bearer <api_key>`

When unauthenticated, the endpoint returns a `401` response with an `WWW-Authenticate` header containing OAuth discovery metadata:

```http
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="mcp",resource_metadata="https://your-studio-instance.com/api/:org/mcp/:connectionId/.well-known/oauth-protected-resource"
```

<Callout type="info">
  Clients supporting OAuth 2.1 can use the resource metadata URL to discover authorization endpoints and complete the OAuth flow automatically.
</Callout>

## How It Works

When a client sends an MCP request through the Connection Proxy:

1. **Authentication**: deco Studio verifies the client's credentials (OAuth token or API key)
2. **Connection Lookup**: deco Studio retrieves the connection configuration and verifies it's active
3. **Authorization**: deco Studio checks if the client has permission to invoke the requested tool
4. **Credential Injection**: deco Studio decrypts stored credentials and injects them into the upstream request
5. **Request Proxying**: deco Studio forwards the MCP request to the upstream server
6. **Monitoring**: deco Studio logs metrics (duration, status, errors) for observability
7. **Response Return**: deco Studio returns the upstream server's response to the client

## Request Format

The Connection Proxy accepts standard MCP protocol requests. The request body should be a JSON-RPC 2.0 message following the MCP specification.

### Example: List Tools

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list"
}
```

### Example: Call Tool

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "github_create_issue",
    "arguments": {
      "repo": "myorg/myrepo",
      "title": "Bug report",
      "body": "Description of the bug"
    }
  }
}
```

## Response Format

Responses follow standard MCP protocol format:

### Success Response

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Issue created successfully: #123"
      }
    ]
  }
}
```

### Error Response

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "error": {
    "code": -32603,
    "message": "Tool execution failed"
  }
}
```

## Authorization

The Connection Proxy enforces fine-grained authorization using deco Studio's permission system:

- **Per-Tool Permissions**: Users must have explicit permission for each tool they invoke
- **Connection-Scoped**: Permissions are scoped to the specific connection
- **Role-Based**: Permissions are inherited from user roles and organization settings

### Permission Format

Permissions are stored in the format:

```json
{
  "<connectionId>": ["tool_name_1", "tool_name_2"]
}
```

### Public Tools

Tools can be marked as public using metadata:

```json
{
  "_meta": {
    "mcp.studio": {
      "public_tool": true
    }
  }
}
```

Public tools allow unauthenticated access and bypass authorization checks.
The legacy `mcp.mesh` metadata key remains accepted for compatibility.

## Error Responses

| Status Code | Description | Example Scenario |
|-------------|-------------|------------------|
| `401` | Unauthorized | No valid OAuth token or API key provided |
| `403` | Forbidden | User lacks permission to invoke the requested tool |
| `404` | Not Found | Connection ID doesn't exist or user doesn't have access |
| `500` | Internal Server Error | Unexpected error during request processing |
| `503` | Service Unavailable | Connection is inactive or upstream server is unreachable |

## Monitoring & Observability

Every request through the Connection Proxy generates:

### Metrics

- **Duration Histograms**: `connection.proxy.duration`
- **Request Counters**: `connection.proxy.requests`
- **Error Counters**: `connection.proxy.errors`

All metrics include labels:
- `connection.id`: The connection UUID
- `tool.name`: The tool being invoked
- `status`: success or error

### Traces

OpenTelemetry spans are created for:
- `mcp.proxy.callTool`: Tool invocations

Traces include attributes:
- `connection.id`: Connection identifier
- `tool.name`: Tool name
- `request.id`: Unique request identifier

## Configuration Options

Connections can be configured with:

### Timeout Settings

The default timeout for tool calls is **5 minutes** (300,000ms). This can be adjusted per connection based on tool execution characteristics.

### Custom Headers

Connections can include custom HTTP headers for authentication or routing:

```json
{
  "connection_headers": {
    "headers": {
      "X-Custom-Header": "value"
    }
  }
}
```

## Use Cases

### Direct MCP Access

Connect Cursor or Claude Desktop directly to a specific upstream MCP:

**Cursor Configuration:**
```json
{
  "mcpServers": {
    "github-production": {
      "url": "https://studio.example.com/api/my-org/mcp/conn_abc123",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
```

### Tool-Specific Clients

Build custom clients that need access to a specific MCP server's tools without going through an agent:

```typescript
const response = await fetch('https://studio.example.com/api/my-org/mcp/conn_abc123', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_API_KEY'
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'tools/call',
    params: {
      name: 'database_query',
      arguments: { query: 'SELECT * FROM users LIMIT 10' }
    }
  })
});
```

### Multi-Tenant Isolation

Each connection is organization-scoped, providing natural tenant isolation:

```
Organization A → conn_123 (GitHub Org A) → GitHub Tools (Org A only)
Organization B → conn_456 (GitHub Org B) → GitHub Tools (Org B only)
```

## Connection States

Connections have a `status` field that affects proxy behavior:

- **`active`**: Connection is ready to proxy requests
- **`inactive`**: Connection is disabled; proxy returns `503` error
- **`error`**: Connection has configuration issues; proxy may fail

## Security Considerations

### Credential Handling

- **Encrypted at Rest**: Credentials are stored encrypted using AES-256-GCM
- **Decrypted Just-in-Time**: Credentials are only decrypted when proxying requests
- **Never Exposed to Clients**: Clients never receive upstream credentials

### Request Validation

- **Schema Validation**: Tool arguments are validated against input schemas
- **Rate Limiting**: (Planned) Per-connection and per-user rate limits
- **Audit Logging**: All tool invocations are logged with user identity

### Network Security

- **TLS Required**: All connections to upstream servers use HTTPS
- **Certificate Validation**: SSL certificates are validated by default
- **Proxy Headers**: Upstream servers receive authenticated requests with credentials

## Comparison with Other Endpoints

| Endpoint | Use Case | Tools Available |
|----------|----------|-----------------|
| `/api/:org/mcp/:connectionId` | Direct access to one upstream MCP | All tools from that connection only |
| `/api/:org/mcp/gateway/:virtualMcpId` | Curated tool surface for an agent (a.k.a. virtual MCP) | Tools from multiple connections, composed |
| `/api/:org/mcp/self` | Management operations | deco Studio management tools only |

<Callout type="tip">
  For most production use cases, use **Agents** (`/api/:org/mcp/gateway/:virtualMcpId`) instead of direct connection proxies. Agents give you control over which tools are exposed and let you compose tools from multiple connections behind one endpoint.
</Callout>

## Related

- [**Connections**](/en/studio/connections) - Understanding the Connection abstraction
- [**Agents**](/en/studio/agents) - Compose tools from multiple connections into a single endpoint
- [**API Keys**](/en/studio/api-keys) - Authentication setup
- [**Monitoring**](/en/studio/monitoring) - Observability and metrics
