Key points
- NopsAI exposes a hosted MCP endpoint at
POST /v1/mcp. - The tool surface is filtered by the calling identity AAA permissions — it is not a privileged back door.
- This is the inverse of MCP Profiles: profiles let NopsAI call out to external servers, while the hosted endpoint lets external clients call in.
- Authenticate with the same bearer tokens the REST API accepts.
Examples
# an empty body defaults to tools/list rather than a parse error
curl -sX POST -H "Authorization: Bearer $NOPSAI_TOKEN" "$NOPSAI_URL/v1/mcp" | jq
# explicit JSON-RPC initialize
curl -sX POST "$NOPSAI_URL/v1/mcp" \
-H "Authorization: Bearer $NOPSAI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"dev"}}}' | jq
# the tools this subject may actually call
curl -sX POST "$NOPSAI_URL/v1/mcp" \
-H "Authorization: Bearer $NOPSAI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | jqHow it works
Because the surface is permission-filtered per caller, two clients with different tokens see different available tools. That is the intended behavior, not a discovery bug.
Use a service account rather than a personal token when an external agent will call the endpoint continuously.
Implementation evidence
doc/mcp-feature-coverage.mdHosted MCP feature coverage and user-scoped permissions.
services/nopsai/hosted_mcp.goEndpoint implementation and permission filtering.

