Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rust/cedar-policy-mcp-schema-generator/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Adds the ability to convert a MCP tool request (and optionally response) to a Cedar request and entity data compliant to the generated Schema.
- Adds support for JSON Schema tuples in MCP tool schemas, which are translated to a record of projections.
- Adds `deduplicate_entity_types` option to consolidate equivalent enum entity types (same name and variants) into a single definition at the lowest common ancestor namespace.

### Changed
- Type arrays in MCP tool schemas now result in records of optional fields (encoding union of types), rather than records of projections (encoding tuples).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
namespace MyMcpServer::tool_a::Input {
entity McpServer enum ["primary", "secondary"];
}

namespace MyMcpServer::tool_b::Input {
entity McpServer enum ["primary", "secondary"];
}

namespace MyMcpServer {
type CommonContext = {
currentTimestamp: datetime,
ipaddr: ipaddr
};

type tool_aInput = {
McpServer?: MyMcpServer::tool_a::Input::McpServer,
query: String
};

type tool_bInput = {
McpServer?: MyMcpServer::tool_b::Input::McpServer,
data: String
};

entity McpServer;

entity User = {
id: String,
username: String
};

action "call_tool";

action "tool_a" in [Action::"call_tool"] appliesTo {
principal: [User],
resource: [McpServer],
context: {
input: tool_aInput,
session: CommonContext
}
};

action "tool_b" in [Action::"call_tool"] appliesTo {
principal: [User],
resource: [McpServer],
context: {
input: tool_bInput,
session: CommonContext
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"result": {
"tools": [
{
"name": "tool_a",
"description": "Tool A with enum named 'McpServer' that collides with existing entity in LCA",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"McpServer": {
"type": "string",
"enum": ["primary", "secondary"],
"description": "Enum that collides with existing McpServer entity type"
},
"query": {
"type": "string",
"description": "The query string"
}
},
"required": ["query"]
}
}
},
{
"name": "tool_b",
"description": "Tool B with same enum named 'McpServer'",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"McpServer": {
"type": "string",
"enum": ["primary", "secondary"],
"description": "Same enum that collides with existing McpServer entity type"
},
"data": {
"type": "string",
"description": "Some data"
}
},
"required": ["data"]
}
}
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
namespace MyMcpServer::tool_a::Input {
entity mode enum ["fast", "slow"];
}

namespace MyMcpServer::tool_b::Input {
entity mode enum ["sync", "async"];
}

namespace MyMcpServer {
type CommonContext = {
currentTimestamp: datetime,
ipaddr: ipaddr
};

type tool_aInput = {
mode?: MyMcpServer::tool_a::Input::mode,
query: String
};

type tool_bInput = {
mode?: MyMcpServer::tool_b::Input::mode,
query: String
};

entity McpServer;

entity User = {
id: String,
username: String
};

action "call_tool";

action "tool_a" in [Action::"call_tool"] appliesTo {
principal: [User],
resource: [McpServer],
context: {
input: tool_aInput,
session: CommonContext
}
};

action "tool_b" in [Action::"call_tool"] appliesTo {
principal: [User],
resource: [McpServer],
context: {
input: tool_bInput,
session: CommonContext
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"result": {
"tools": [
{
"name": "tool_a",
"description": "Tool A with enum 'mode' having variants fast/slow",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": ["fast", "slow"],
"description": "Mode for tool A"
},
"query": {
"type": "string",
"description": "The query string"
}
},
"required": ["query"]
}
}
},
{
"name": "tool_b",
"description": "Tool B with enum 'mode' having different variants sync/async",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": ["sync", "async"],
"description": "Mode for tool B - different variants from tool A"
},
"query": {
"type": "string",
"description": "The query string"
}
},
"required": ["query"]
}
}
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
namespace MyMcpServer {
type CommonContext = {
currentTimestamp: datetime,
ipaddr: ipaddr
};

type tool_aInput = {
mode?: MyMcpServer::tool_a_Input_mode,
query: String
};

type tool_bInput = {
mode?: MyMcpServer::tool_b_Input_mode,
query: String
};

entity McpServer;

entity User = {
id: String,
username: String
};

entity tool_a_Input_mode enum ["fast", "slow"];

entity tool_b_Input_mode enum ["sync", "async"];

action "call_tool";

action "tool_a" in [Action::"call_tool"] appliesTo {
principal: [User],
resource: [McpServer],
context: {
input: tool_aInput,
session: CommonContext
}
};

action "tool_b" in [Action::"call_tool"] appliesTo {
principal: [User],
resource: [McpServer],
context: {
input: tool_bInput,
session: CommonContext
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
namespace MyMcpServer::tool_x::Input::B {
entity C = {
priority?: MyMcpServer::tool_x::Input::priority,
value_c: String
};

entity D = {
priority?: MyMcpServer::tool_x::Input::priority,
value_d: Long
};
}

namespace MyMcpServer::tool_x::Input::E {
entity F = {
priority?: MyMcpServer::tool_x::Input::priority,
value_f: Bool
};
}

namespace MyMcpServer::tool_x::Input {
entity B = {
C: MyMcpServer::tool_x::Input::B::C,
D: MyMcpServer::tool_x::Input::B::D
};

entity E = {
F: MyMcpServer::tool_x::Input::E::F
};

entity priority enum ["high", "medium", "low"];
}

namespace MyMcpServer {
type CommonContext = {
currentTimestamp: datetime,
ipaddr: ipaddr
};

type tool_xInput = {
B: MyMcpServer::tool_x::Input::B,
E: MyMcpServer::tool_x::Input::E
};

entity McpServer;

entity User = {
id: String,
username: String
};

action "call_tool";

action "tool_x" in [Action::"call_tool"] appliesTo {
principal: [User],
resource: [McpServer],
context: {
input: tool_xInput,
session: CommonContext
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"result": {
"tools": [
{
"name": "tool_x",
"description": "Tool X with same enum at different nested depths to test LCA computation",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"B": {
"type": "object",
"properties": {
"C": {
"type": "object",
"properties": {
"priority": {
"type": "string",
"enum": ["high", "medium", "low"],
"description": "Shared enum in B::C"
},
"value_c": {
"type": "string",
"description": "A value in C"
}
},
"required": ["value_c"]
},
"D": {
"type": "object",
"properties": {
"priority": {
"type": "string",
"enum": ["high", "medium", "low"],
"description": "Shared enum in B::D"
},
"value_d": {
"type": "integer",
"description": "A value in D"
}
},
"required": ["value_d"]
}
},
"required": ["C", "D"]
},
"E": {
"type": "object",
"properties": {
"F": {
"type": "object",
"properties": {
"priority": {
"type": "string",
"enum": ["high", "medium", "low"],
"description": "Shared enum in E::F"
},
"value_f": {
"type": "boolean",
"description": "A value in F"
}
},
"required": ["value_f"]
}
},
"required": ["F"]
}
},
"required": ["B", "E"]
}
}
}
]
}
}
Loading
Loading