Service-to-Service Mode
Service-to-service mode is for hosted MCP servers that run alongside your application infrastructure. It provides the full set of MCP integration endpoints including deployment resolution, entitlement checking, usage recording, and credit cost lookups.
Authentication
Service-to-service endpoints authenticate via the X-MCP-Service-Key header. This is a shared secret configured on both the HiveForge API and your MCP server.
X-MCP-Service-Key: your-shared-secret-keySet the HIVEFORGE_MCP_SERVICE_KEY environment variable on the HiveForge API to match.
The service key grants access to entitlement and usage operations for all deployments. Treat it with the same care as a database credential.
Endpoints
All endpoints use the base URL: https://api.hiveforge.dev/api/v1/mcp
Resolve Deployment
Map an authenticated user to their active HiveForge deployment. This is the first call your MCP server should make when a new session starts.
GET /api/v1/mcp/resolve-deployment?user_id={user_id}Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
user_id | string | Yes | Supabase auth user ID |
Response
| Field | Type | Description |
|---|---|---|
deployment_id | string|null | Resolved deployment UUID |
organization_id | string|null | Organization UUID |
tier | string|null | Entitlement tier (sandbox, trial, launch, growth, enterprise) |
mcp_enabled | boolean | Whether MCP is enabled for this tier |
error | string|null | Error code if resolution failed |
Results are cached server-side for 5 minutes. Subsequent requests for the same user_id within the cache window are served from memory.
curl "https://api.hiveforge.dev/api/v1/mcp/resolve-deployment?user_id=abc-123-def" \
-H "X-MCP-Service-Key: your-shared-secret-key"Example response:
{
"deployment_id": "d9f2a1b4-7c3e-4f8a-b5d6-1e2f3a4b5c6d",
"organization_id": "org-a1b2c3d4",
"tier": "launch",
"mcp_enabled": true,
"error": null
}Example error response:
{
"deployment_id": null,
"organization_id": null,
"tier": null,
"mcp_enabled": false,
"error": "no_deployment_found"
}Check Entitlement
Verify whether a deployment is entitled to use a specific MCP tool.
POST /api/v1/mcp/check-entitlementRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
deployment_id | string | Yes | HiveForge deployment UUID |
tool_name | string | Yes | MCP tool name to check access for |
Response
| Field | Type | Description |
|---|---|---|
allowed | boolean | Whether the tool call is permitted |
tier | string|null | Deployment's entitlement tier |
credit_cost | integer | Credits that will be deducted |
credits_available | integer|null | Current credit balance |
reason | string|null | Denial reason if allowed is false |
Your MCP server should cache entitlement results for up to 5 minutes to reduce API calls.
curl -X POST https://api.hiveforge.dev/api/v1/mcp/check-entitlement \
-H "X-MCP-Service-Key: your-shared-secret-key" \
-H "Content-Type: application/json" \
-d '{
"deployment_id": "d9f2a1b4-7c3e-4f8a-b5d6-1e2f3a4b5c6d",
"tool_name": "hornethive_execute_crew"
}'Example response (allowed):
{
"allowed": true,
"tier": "launch",
"credit_cost": 5,
"credits_available": 9450,
"reason": null
}Example response (denied):
{
"allowed": false,
"tier": "sandbox",
"credit_cost": 0,
"credits_available": null,
"reason": "sandbox_tier"
}Record Usage
Record a completed MCP tool invocation and deduct credits. Call this after the tool executes successfully.
POST /api/v1/mcp/usageRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
deployment_id | string | Yes | HiveForge deployment UUID |
tool_name | string | Yes | MCP tool name that was executed |
mcp_user_id | string|null | No | End-user ID from the MCP session |
metadata | object|null | No | Arbitrary metadata for audit trail |
Response
| Field | Type | Description |
|---|---|---|
success | boolean | Whether credits were deducted |
credits_used | integer | Number of credits deducted |
credits_remaining | integer|null | Remaining credit balance |
error | string|null | Error description if deduction failed |
curl -X POST https://api.hiveforge.dev/api/v1/mcp/usage \
-H "X-MCP-Service-Key: your-shared-secret-key" \
-H "Content-Type: application/json" \
-d '{
"deployment_id": "d9f2a1b4-7c3e-4f8a-b5d6-1e2f3a4b5c6d",
"tool_name": "hornethive_execute_crew",
"mcp_user_id": "user-456",
"metadata": {
"crew_id": "content-pipeline",
"duration_ms": 4520
}
}'Example response:
{
"success": true,
"credits_used": 5,
"credits_remaining": 9445,
"error": null
}Get Credit Costs
Retrieve the current credit costs for all MCP tool actions. Use this to display costs to users or to pre-validate tool calls client-side.
GET /api/v1/mcp/credit-costsNo request body required.
Response
| Field | Type | Description |
|---|---|---|
costs | array | List of credit cost entries |
costs[].action | string | Credit action name |
costs[].credits | integer | Credit cost per invocation |
costs[].description | string|null | Human-readable description |
Your MCP server should cache this response for up to 1 hour. Credit costs change infrequently.
curl https://api.hiveforge.dev/api/v1/mcp/credit-costs \
-H "X-MCP-Service-Key: your-shared-secret-key"Example response:
{
"costs": [
{ "action": "task_basic", "credits": 1, "description": null },
{ "action": "task_advanced", "credits": 3, "description": null },
{ "action": "crew_execute", "credits": 5, "description": null },
{ "action": "rag_query", "credits": 2, "description": null },
{ "action": "rag_ingest", "credits": 2, "description": null },
{ "action": "generate", "credits": 3, "description": null },
{ "action": "tao_trace", "credits": 1, "description": null },
{ "action": "tao_evaluate", "credits": 3, "description": null },
{ "action": "tao_analytics", "credits": 2, "description": null },
{ "action": "platform_basic", "credits": 1, "description": null }
]
}Full Integration Pattern
Here is the recommended flow for a hosted MCP server:
class HiveForgeMCPMiddleware:
"""Middleware for metering MCP tool calls through HiveForge."""
def __init__(self, api_url: str, service_key: str):
self.api_url = api_url
self.headers = {"X-MCP-Service-Key": service_key}
self._deployment_cache: dict[str, dict] = {}
async def handle_tool_call(self, user_id: str, tool_name: str, execute_fn, **kwargs):
# Step 1: Resolve deployment (cached)
deployment = self._deployment_cache.get(user_id)
if not deployment:
deployment = await self._resolve(user_id)
if deployment.get("error"):
return {"error": deployment["error"]}
self._deployment_cache[user_id] = deployment
if not deployment.get("mcp_enabled"):
return {"error": "MCP not enabled for this tier"}
dep_id = deployment["deployment_id"]
# Step 2: Check entitlement
entitlement = await self._check_entitlement(dep_id, tool_name)
if not entitlement["allowed"]:
return {"error": f"Denied: {entitlement['reason']}"}
# Step 3: Execute the tool
result = await execute_fn(**kwargs)
# Step 4: Record usage
await self._record_usage(dep_id, tool_name, user_id)
return result