Packages
corex
0.1.2
0.1.2
0.1.1
0.1.0
0.1.0-rc.1
0.1.0-rc.0
0.1.0-beta.5
0.1.0-beta.4
0.1.0-beta.3
0.1.0-beta.2
0.1.0-beta.1
0.1.0-alpha.33
0.1.0-alpha.32
0.1.0-alpha.31
0.1.0-alpha.30
0.1.0-alpha.29
0.1.0-alpha.28
0.1.0-alpha.27
0.1.0-alpha.26
0.1.0-alpha.25
0.1.0-alpha.24
0.1.0-alpha.23
0.1.0-alpha.22
0.1.0-alpha.21
0.1.0-alpha.20
0.1.0-alpha.19
0.1.0-alpha.18
0.1.0-alpha.17
0.1.0-alpha.16
0.1.0-alpha.15
0.1.0-alpha.14
0.1.0-alpha.13
0.1.0-alpha.12
0.1.0-alpha.11
0.1.0-alpha.10
0.1.0-alpha.9
0.1.0-alpha.8
0.1.0-alpha.7
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
Accessible and unstyled UI components library written in Elixir and TypeScript that integrates Zag.js state machines into the Phoenix Framework.
Current section
Files
Jump to
Current section
Files
lib/mcp/router.ex
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) 2025 Dashbit
# See LICENSE for third-party notices.
defmodule Corex.MCP.Router do
@moduledoc false
use Plug.Router
import Plug.Conn
require Logger
alias Corex.Json
alias Corex.MCP.Server
@remote_access_forbidden """
For security reasons, Corex.MCP does not accept remote connections by default.
If you really want to allow remote connections, configure plug Corex.MCP with allow_remote_access: true.
"""
@origin_header_forbidden """
For security reasons, Corex.MCP does not accept requests with an origin header for this endpoint.
"""
@json_parser Plug.Parsers.init(
parsers: [:json],
pass: [],
json_decoder: Json.encoder()
)
plug(:match)
plug(:check_remote_ip)
plug(:check_origin)
plug(:dispatch)
get "/" do
conn
|> put_resp_content_type("text/html")
|> send_resp(200, landing_html())
|> halt()
end
get "/config" do
conn
|> put_resp_content_type("application/json")
|> send_resp(200, Json.encode_to_iodata!(client_config()))
|> halt()
end
get "/mcp" do
conn
|> put_logger_metadata()
|> send_resp(405, "Method Not Allowed")
|> halt()
end
post "/mcp" do
conn
|> put_logger_metadata()
|> Plug.Parsers.call(@json_parser)
|> Server.handle_http_message()
|> halt()
end
match "/*_ignored" do
conn
|> put_logger_metadata()
|> send_resp(404, "Not Found")
|> halt()
end
defp check_remote_ip(conn, _opts) do
config = conn.private.corex_mcp_config
cond do
local_address?(conn.remote_ip) ->
conn
config.allow_remote_access ->
conn
true ->
Logger.warning(@remote_access_forbidden)
conn
|> send_resp(403, @remote_access_forbidden)
|> halt()
end
end
defp local_address?({127, 0, 0, _}), do: true
defp local_address?({0, 0, 0, 0, 0, 0, 0, 1}), do: true
defp local_address?({0, 0, 0, 0, 0, 65_535, 32_512, 1}), do: true
defp local_address?(_), do: false
defp check_origin(conn, _opts) do
case {conn.path_info, get_req_header(conn, "origin")} do
{[], _} ->
conn
{_, []} ->
conn
{_, _} ->
Logger.warning(@origin_header_forbidden)
conn
|> send_resp(403, @origin_header_forbidden)
|> halt()
end
end
defp put_logger_metadata(conn) do
Logger.metadata(corex_mcp: true)
conn
end
defp landing_html do
"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Corex MCP</title>
</head>
<body>
<p>Corex Model Context Protocol (dev). Use POST to <code>/corex/mcp</code> for JSON-RPC.</p>
</body>
</html>
"""
end
defp client_config do
%{
name: "corex",
framework_type: "phoenix",
corex_version: package_version(:corex)
}
end
defp package_version(app) do
case Application.spec(app, :vsn) do
nil -> nil
vsn -> List.to_string(vsn)
end
end
end