Page Menu
Home
VyOS Platform
Search
Configure Global Search
Log In
Files
F116353133
T9030-mcp-architecture.md
All Users
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
mihakralj
Jul 1 2026, 2:50 AM
2026-07-01 02:50:46 (UTC+0)
Size
9 KB
Referenced Files
None
Subscribers
None
T9030-mcp-architecture.md
View Options
#
T9030
:
MCP
Architecture
&
Transport
Layer
|
Field
|
Value
|
|-------|-------|
|
Task
|
[
T9030
](
https
:
//vyos.dev/T9030) |
|
Status
|
Draft
/
design
|
|
Component
|
`
service
https
api
mcp
`
|
|
Target
branch
|
`
current
`
(
1.5
+)
|
|
Related
specs
|
[
Dynamic
Schema
Harvesting
](
T9030
-
mcp
-
dynamic
-
schema
.
md
)
·
[
MCP
Tools
](
T9030
-
mcp
-
tools
.
md
)
·
[
Security
&
Concurrency
](
T9030
-
mcp
-
security
.
md
)
|
##
Overview
Integrate
a
native
HTTPS
-
based
Model
Context
Protocol
(
MCP
)
server
into
VyOS
,
running
alongside
`
set
service
https
api
rest
`
and
`
set
service
https
api
graphql
`
.
The
server
lets
MCP
-
capable
LLM
clients
(
Claude
Desktop
,
IDE
agents
,
custom
orchestrators
)
drive
VyOS
operational
and
configuration
workflows
through
a
standard
,
typed
protocol
instead
of
bespoke
REST
glue
.
The
server
must
harvest
all
tools
and
data
dynamically
from
the
VyOS
internal
schema
,
ensuring
zero
maintenance
as
the
OS
evolves
.
**
Key
constraint
**:
all
tools
,
resources
,
and
schemas
are
derived
on
-
the
-
fly
from
`
interface
-
definitions
/
`
and
`
op
-
mode
-
definitions
/
`
XML
templates
via
the
`
vyos
.
xml_ref
`
reference
cache
(
`
vyos
.
xml_ref
.
cache
.
reference
`
for
config
nodes
,
`
vyos
.
xml_ref
.
op_cache
.
op_reference
`
for
op
-
mode
nodes
).
No
static
`
@
mcp
.
tool
()
`
definitions
are
committed
to
the
tree
.
###
Goals
-
Expose
the
full
VyOS
CLI
surface
(
op
-
mode
+
conf
-
mode
)
to
MCP
clients
with
**
no
per
-
feature
code
**.
-
Reuse
the
existing
HTTPS
API
daemon
,
authentication
,
and
TLS
termination
—
no
new
listening
socket
,
no
new
systemd
unit
.
-
Guarantee
that
an
LLM
can
only
issue
paths
that
exist
in
the
live
schema
,
eliminating
arbitrary
shell
execution
and
command
hallucination
.
-
Stay
invisible
/
disabled
by
default
;
opt
-
in
via
a
single
`
set
`
command
.
###
Non
-
goals
-
stdio
transport
(
local
subprocess
MCP
)
—
not
applicable
to
a
network
appliance
.
-
A
separate
OAuth
2.1
authorization
server
—
auth
is
inherited
from
the
existing
API
layer
(
see
[
Security
spec
](
T9030
-
mcp
-
security
.
md
)).
-
Replacing
REST
/
GraphQL
—
MCP
is
an
additional
,
parallel
surface
.
###
Terminology
|
Term
|
Meaning
|
|------|---------|
|
Tool
|
An
MCP
-
invokable
action
(
`
execute_operational_command
`
,
`
modify_configuration
`
).
|
|
Resource
|
Read
-
only
,
addressable
data
exposed
via
a
URI
template
(
config
/
state
/
schema
).
|
|
Prompt
|
A
reusable
templated
instruction
set
surfaced
to
the
LLM
.
|
|
Meta
-
tool
|
A
single
generic
tool
that
accepts
a
path
array
,
instead
of
thousands
of
generated
tools
.
|
|
Reference
cache
|
Compiled
XML
schema
(
`
reftree
.
cache
`
)
consulted
for
path
validation
.
|
##
Transport
:
Streamable
HTTP
-
Protocol
:
JSON
-
RPC
2.0
over
Streamable
HTTP
.
-
stdio
transport
is
**
not
**
supported
—
incompatible
with
remote
network
devices
.
-
Operates
natively
over
HTTPS
port
443
,
traverses
reverse
proxies
and
firewalls
.
-
Uses
`
mcp
.
server
.
streamable_http_manager
.
StreamableHTTPSessionManager
`
from
the
MCP
Python
SDK
,
mounted
as
an
ASGI
sub
-
application
.
Sessions
are
stateful
:
the
initial
GET
establishes
an
SSE
stream
and
returns
a
`
Mcp
-
Session
-
Id
`
header
;
subsequent
POST
requests
carry
that
session
ID
.
DELETE
terminates
the
session
.
###
Endpoints
|
Method
|
Path
|
Purpose
|
|--------|--------|------------------------------------------------------|
|
GET
|
`
/
mcp
`
|
Establish
SSE
stream
,
negotiate
session
|
|
POST
|
`
/
mcp
`
|
Client
-
to
-
server
JSON
-
RPC
messages
(
with
session
ID
)
|
|
DELETE
|
`
/
mcp
`
|
Terminate
session
|
The
single
`
/
mcp
`
endpoint
handles
all
MCP
traffic
.
The
initial
GET
returns
the
`
Mcp
-
Session
-
Id
`
header
for
session
correlation
.
The
POST
channel
carries
JSON
-
RPC
requests
scoped
to
that
session
.
The
DELETE
allows
clean
client
-
initiated
teardown
.
###
Client
Configuration
Example
Orchestrators
(
e
.
g
.
Claude
Desktop
,
Cline
)
connecting
to
this
MCP
server
should
configure
the
connection
matching
the
Streamable
HTTP
standard
and
providing
the
authentication
headers
.
```
json
{
"mcpServers"
:
{
"vyos-router"
:
{
"url"
:
"https://<router-ip>/mcp"
,
"headers"
:
{
"apikey"
:
"<vyos-api-key>"
}
}
}
}
```
*
Note
:
Due
to
typical
orchestrator
limitations
regarding
custom
headers
,
it
may
be
required
to
pass
the
API
key
via
query
parameters
or
environment
variables
depending
on
client
implementation
,
or
require
a
lightweight
local
proxy
for
the
standard
`
apikey
`
header
.*
###
Connection
sequence
```
mermaid
sequenceDiagram
participant
C
as
MCP
Client
(
LLM
)
participant
P
as
FastAPI
/
ApiServer
participant
A
as
Auth
dependency
participant
M
as
api
.
mcp
.
routers
(
Streamable
HTTP
app
)
C
->>
P
:
GET
/
mcp
(
apikey
/
Bearer
)
P
->>
A
:
validate
credentials
A
-->>
P
:
401
if
invalid
(
no
handshake
)
P
->>
M
:
open
SSE
stream
,
create
session
M
-->>
C
:
SSE
stream
+
Mcp
-
Session
-
Id
header
C
->>
P
:
POST
/
mcp
{
initialize
}
(
Mcp
-
Session
-
Id
)
P
->>
M
:
route
by
session
id
M
-->>
C
:
SSE
:
initialize
result
(
capabilities
)
C
->>
P
:
POST
/
mcp
{
tools
/
list
}
(
Mcp
-
Session
-
Id
)
M
-->>
C
:
SSE
:
tool
catalog
(
mode
-
filtered
)
C
->>
P
:
POST
/
mcp
{
tools
/
call
...}
(
Mcp
-
Session
-
Id
)
M
-->>
C
:
SSE
:
result
/
JSON
-
RPC
error
C
->>
P
:
DELETE
/
mcp
(
Mcp
-
Session
-
Id
)
M
-->>
C
:
session
terminated
```
###
Transport
-
level
error
handling
-
Credential
failure
on
the
initial
`
GET
/
mcp
`
returns
HTTP
401
and
the
SSE
stream
is
never
opened
—
the
client
cannot
enumerate
tools
or
resources
.
-
A
POST
referencing
an
unknown
/
expired
session
id
returns
HTTP
404
;
the
client
must
re
-
establish
the
session
via
a
new
GET
.
-
Protocol
/
parse
failures
are
returned
as
JSON
-
RPC
`
error
`
objects
over
the
SSE
stream
(
codes
per
the
JSON
-
RPC
2.0
/
MCP
spec
),
never
as
raw
HTML
.
##
Integration
into
VyOS
HTTP
API
-
Embed
MCP
as
an
`
api
.
mcp
.
routers
`
module
,
parallel
to
`
api
.
rest
.
routers
`
and
`
api
.
graphql
.
routers
`
under
`
src
/
services
/
api
/
`
.
-
Mount
the
MCP
ASGI
app
onto
the
existing
FastAPI
instance
via
`
app
.
mount
(
"/mcp"
,
_mcp_asgi_app
)
`
(
analogous
to
how
GraphQL
adds
its
route
).
-
Reuses
the
existing
`
ApiServer
(
UvicornServer
)
`
defined
in
`
src
/
services
/
vyos
-
http
-
api
-
server
`
—
no
new
daemons
,
no
new
socket
(
the
server
already
binds
the
unix
domain
socket
`
/
run
/
api
.
sock
`
).
-
The
module
is
loaded
/
unloaded
dynamically
based
on
`
api_config_state
`
(
`
/
run
/
http
-
api
-
state
`
),
exactly
like
REST
and
GraphQL
:
`
mcp_init
(
app
)
`
/
`
mcp_clear
(
app
)
`
mirror
`
rest_init
`
/
`
rest_clear
`
and
`
graphql_init
`
/
`
graphql_clear
`
.
-
Inherits
FastAPI
dependency
injection
for
auth
(
API
keys
,
JWT
)
via
a
wrapper
ASGI
app
that
validates
credentials
before
delegating
to
the
session
manager
.
###
Module
layout
```
src
/
services
/
api
/
mcp
/
├──
__init__
.
py
├──
routers
.
py
#
mcp_init
/
mcp_clear
,
Streamable
HTTP
mount
,
auth
wrapper
├──
server
.
py
#
MCP
Server
instance
,
capability
registration
├──
tools
.
py
#
meta
-
tool
dispatch
(
see
T9030
-
mcp
-
tools
.
md
)
├──
resources
.
py
#
URI
-
template
resources
(
see
T9030
-
mcp
-
dynamic
-
schema
.
md
)
├──
schema
.
py
#
XML
reference
->
JSON
Schema
projection
├──
prompts
.
py
#
reusable
prompt
templates
└──
auth
.
py
#
credential
extraction
at
the
handshake
(
see
Security
spec
)
```
###
Router
registration
pattern
`
vyos
-
http
-
api
-
server
`
already
branches
on
the
parsed
config
state
to
wire
each
sub
-
API
.
MCP
follows
the
same
idempotent
init
/
clear
contract
:
```
python
#
in
vyos
-
http
-
api
-
server
,
alongside
rest
/
graphql
wiring
if
session
.
mcp
:
from
api
.
mcp
.
routers
import
mcp_init
mcp_init
(
app
)
else
:
from
api
.
mcp
.
routers
import
mcp_clear
mcp_clear
(
app
)
```
`
mcp_init
(
app
)
`
is
idempotent
(
no
-
op
if
already
mounted
,
mirroring
how
`
rest_init
`
guards
with
`
all
(
r
in
app
.
routes
for
r
in
router
.
routes
)
`
)
and
`
mcp_clear
(
app
)
`
removes
the
mounted
sub
-
app
from
`
app
.
routes
`
.
In
-
flight
connections
terminate
when
the
worker
reloads
(
the
server
is
torn
down
and
`
initialization
()
`
re
-
runs
on
`
SIGHUP
`
);
`
mcp_clear
`
cancels
the
session
manager
lifespan
,
terminating
all
active
sessions
.
##
Dependencies
-
`
python3
-
mcp
`
(
MCP
Python
SDK
)
—
added
to
`
debian
/
control
`
build
/
runtime
deps
for
the
`
vyos
-
1
x
`
package
.
The
SDK
supplies
`
mcp
.
server
.
Server
`
,
`
mcp
.
server
.
streamable_http
.
StreamableHTTPServerTransport
`
,
`
mcp
.
server
.
streamable_http_manager
.
StreamableHTTPSessionManager
`
,
and
the
JSON
-
RPC
types
.
-
No
new
compiled
component
;
the
feature
is
pure
Python
on
top
of
the
existing
FastAPI
/
Uvicorn
stack
already
required
by
the
HTTP
API
.
-
Reference
cache
(
`
reftree
.
cache
`
/
`
op_cache
`
)
is
produced
during
image
build
by
the
existing
`
vyos
.
xml_ref
`
tooling
—
no
additional
build
step
.
##
Lifecycle
Management
-
`
ApiServer
(
UvicornServer
)
`
explicitly
overrides
`
install_signal_handlers
()
`
(
it
is
a
no
-
op
)
to
prevent
interference
with
the
VyOS
systemd
manager
;
the
MCP
sub
-
app
inherits
this
and
adds
no
signal
handling
of
its
own
.
-
The
MCP
SDK
Streamable
HTTP
transport
is
fully
ASGI
compliant
—
no
background
threads
or
signal
hijacking
required
.
The
session
manager
runs
its
task
group
within
the
app
lifespan
,
managed
by
`
app
.
router
.
lifespan_context
`
.
-
On
`
service_https
.
py
`
commit
,
the
API
state
file
is
rewritten
and
the
running
server
reconciles
routers
(
mount
/
unmount
MCP
)
without
restarting
the
process
;
REST
and
GraphQL
connections
are
unaffected
(
see
[
Reconfiguration
Behavior
](
T9030
-
mcp
-
security
.
md
#
reconfiguration
-
behavior
)).
##
Open
questions
-
Whether
to
expose
a
dedicated
MCP
listen
port
distinct
from
443
.
Deferred
:
the
initial
implementation
shares
the
single
Uvicorn
socket
(
`
/
run
/
api
.
sock
`
),
so
no
`
port
`
CLI
node
is
shipped
until
the
transport
is
actually
decoupled
(
see
[
CLI
Configuration
](
T9030
-
mcp
-
security
.
md
#
cli
-
configuration
)).
File Metadata
Details
Attached
Mime Type
text/plain
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3820425
Default Alt Text
T9030-mcp-architecture.md (9 KB)
Attached To
Mode
T9030: Native HTTPS Model Context Protocol (MCP) API Endpoint
Attached
Detach File
Event Timeline
Log In to Comment