MCP
Register Model Context Protocol servers, authorize discovered tools one at a time, and invoke them through the gateway.
Model Context Protocol servers expose tools to agents. Veefore treats an MCP server as an untrusted tool source: you register it, you discover what it offers, and then a human authorizes each tool individually.
Discovery and authorization are separate steps
A newly discovered MCP tool is unauthorized until someone authorizes it.
If discovery granted access, an MCP server could widen its own reach by adding a tool — you would connect to it for one capability and silently acquire however many it chose to expose later. Separating the steps means the server proposes and you decide.
#Register a server
bashcurl -X POST https://veefore.example.com/v1/mcp/servers \
-H "Authorization: Bearer $VEEFORE_API_KEY" \
-H 'content-type: application/json' \
-d '{
"key": "internal-tools",
"name": "Internal tooling MCP server",
"transport": "HTTP",
"endpoint_url": "https://mcp.internal.example.com",
"credential_id": "cred_01JAV…"
}'
The server starts PENDING. It cannot be used until it is approved, and no
agent can reach anything through it in the meantime.
#Discover its tools
bashcurl -X POST https://veefore.example.com/v1/mcp/servers/mcp_01ABC/discover \
-H "Authorization: Bearer $VEEFORE_API_KEY"
Returns the tool list the server advertises, with each tool's schema and description. Every one of them is unauthorized.
Read the list before authorizing anything. A tool named run_query with free-
text SQL is a different proposition from get_ticket, and the names are chosen
by the server, not by you.
#Authorize, one at a time
bashcurl -X POST https://veefore.example.com/v1/mcp/servers/mcp_01ABC/tools/tool_01XYZ/authorize \
-H "Authorization: Bearer $VEEFORE_API_KEY"
An authorized MCP tool behaves like any other tool from here: it requires a capability, it is subject to policy, and it goes through the full pipeline.
Authorize what your agents actually need. "All of them" is not a decision.
#Call it
tsconst decision = await agent.veefore.mcpCall({
server: 'internal-tools',
tool: 'search_tickets',
arguments: { query: 'refund failed', limit: 20 },
});
pythondecision = agent.veefore.mcp_call(
server="internal-tools",
tool="search_tickets",
arguments={"query": "refund failed", "limit": 20},
)
Over the wire: POST /gateway/v1/mcp/call. The same twelve-stage pipeline
applies — same decisions, same action record, same audit trail. An MCP tool is
not a side door.
#Re-discovery
Servers add and remove tools. Running discovery again updates the list, and newly discovered tools arrive unauthorized — including on a server whose other tools you have already authorized.
Make re-discovery a routine thing you do and look at, rather than something that happens implicitly. A tool appearing in the list is the server telling you it would like more reach.
#Disable a tool
bashcurl -X POST https://veefore.example.com/v1/mcp/servers/mcp_01ABC/tools/tool_01XYZ/disable \
-H "Authorization: Bearer $VEEFORE_API_KEY"
Immediate. Refused with TOOL_DISABLED.
To cut off a whole server, disable its tools or revoke its credential. A server
that is not trusted is refused with MCP_SERVER_NOT_TRUSTED.
#Transport
veefore doctor audits MCP transport and authorization, and reports:
- A server reachable over plaintext HTTP to a non-loopback host
- Tools authorized but never used — reach you are carrying for nothing
- Servers in
PENDINGfor a long time — someone started and did not finish - A server with no credential, calling an endpoint that presumably wants one
#Policy on MCP
tool.kind is MCP and tool.protocol is MCP, so you can write rules that
apply to MCP specifically:
json{
"id": "rule-mcp-needs-approval-in-prod",
"name": "MCP tools need approval in production",
"priority": 600,
"enabled": true,
"when": {
"kind": "group",
"id": "g-mcp-prod",
"operator": "and",
"children": [
{ "kind": "condition", "id": "c-kind", "field": "tool.kind", "operator": "eq", "value": "MCP" },
{
"kind": "condition",
"id": "c-env",
"field": "environment.type",
"operator": "eq",
"value": "PRODUCTION"
}
]
},
"then": {
"decision": "REQUIRE_APPROVAL",
"reason": "Third-party MCP tools require a human decision in production.",
"approval": { "routingMode": "SINGLE", "requiredApprovals": 1, "ttlSeconds": 900 }
}
}
A good default for a server you do not operate yourself. It can be relaxed per tool once you have watched specific ones behave.
#Practical advice
Treat an MCP server as a dependency with privileges. It gets a credential, it gets reached over the network, and its tool list is under its control. Review it the way you would review a library you are about to add.
Authorize narrowly, and revisit. A tool authorized for a one-off task and never revoked is standing reach nobody remembers granting.
Prefer MCP servers you run. A server on your own infrastructure with its own credential is a very different risk profile from a public one.