pub struct InMemoryMCPToolServer { /* private fields */ }Implementations§
Source§impl InMemoryMCPToolServer
impl InMemoryMCPToolServer
Sourcepub fn new() -> Self
pub fn new() -> Self
Examples found in repository?
examples/mcp_governance.rs (line 36)
33fn main() -> agentledger::Result<()> {
34 let mut runtime = Runtime::new();
35 runtime.set_sandbox(Box::new(DemoSandboxExecutor));
36 let mut server = InMemoryMCPToolServer::new();
37 server.add_tool(
38 state(&[
39 ("name", "mcp.github.create_pr".into()),
40 (
41 "inputSchema",
42 Value::Object(state(&[
43 ("type", "object".into()),
44 (
45 "required",
46 Value::Array(vec![Value::String("title".to_string())]),
47 ),
48 (
49 "properties",
50 Value::Object(state(&[(
51 "title",
52 Value::Object(state(&[
53 ("type", "string".into()),
54 ("minLength", 1_i64.into()),
55 ])),
56 )])),
57 ),
58 ])),
59 ),
60 (
61 "annotations",
62 Value::Object(state(&[
63 ("side_effect", "external_write".into()),
64 ("risk_level", "high".into()),
65 ("idempotency_required", true.into()),
66 ("approval_required", true.into()),
67 ("sandbox_required", true.into()),
68 (
69 "sandbox_policy",
70 Value::Object(state(&[
71 ("network", "deny".into()),
72 ("filesystem", "read-only".into()),
73 ])),
74 ),
75 ])),
76 ),
77 ]),
78 create_pr,
79 );
80 let adapter = MCPToolAdapter { client_call: create_pr };
81 for descriptor in server.list_tools() {
82 runtime.register_tool(adapter.tool_spec_from_descriptor(&descriptor));
83 }
84
85 let (run_id, _) = runtime.create_run(State::new());
86 let first_claim = runtime.store.claim_step("worker-before-approval", &run_id, 60.0)?;
87 let first_ctx = AgentContext {
88 run_id: run_id.clone(),
89 session_id: first_claim.session_id.clone(),
90 step_id: first_claim.step_id.clone(),
91 agent_role: "MCPAgent".to_string(),
92 lease_token: first_claim.lease_token.clone(),
93 attempt: first_claim.attempt,
94 state_version: first_claim.state_version,
95 pending_patch: State::new(),
96 };
97 let first = runtime.call_tool(
98 &first_ctx,
99 "mcp.github.create_pr",
100 state(&[
101 ("title", "Update runtime docs".into()),
102 ("_logical_operation", "docs-pr".into()),
103 ]),
104 );
105 let approval_id = first
106 .unwrap_err()
107 .0
108 .trim_start_matches("approval required:")
109 .to_string();
110 runtime.store.mark_waiting_human(
111 &run_id,
112 &first_ctx.step_id,
113 "approval required for tool mcp.github.create_pr",
114 &approval_id,
115 );
116 runtime
117 .store
118 .approve_request(&approval_id, "maintainer", "demo approval")?;
119
120 let second_claim = runtime.store.claim_step("worker-after-approval", &run_id, 60.0)?;
121 let mut second_ctx = AgentContext {
122 run_id: run_id.clone(),
123 session_id: second_claim.session_id.clone(),
124 step_id: second_claim.step_id.clone(),
125 agent_role: "MCPAgent".to_string(),
126 lease_token: second_claim.lease_token.clone(),
127 attempt: second_claim.attempt,
128 state_version: second_claim.state_version,
129 pending_patch: State::new(),
130 };
131 let result = runtime.call_tool(
132 &second_ctx,
133 "mcp.github.create_pr",
134 state(&[
135 ("title", "Update runtime docs".into()),
136 ("_logical_operation", "docs-pr".into()),
137 ]),
138 )?;
139 second_ctx.write_state("pull_request", result);
140 runtime.store.commit_state_patch(
141 &run_id,
142 &second_ctx.step_id,
143 &second_ctx.lease_token,
144 second_ctx.state_version,
145 second_ctx.pending_patch,
146 )?;
147
148 let approvals = runtime.store.approval_requests(&run_id);
149 println!(
150 "{{\n \"run_id\": \"{}\",\n \"first_attempt_waited_for_approval\": true,\n \"second_attempt_ok\": true,\n \"approval_count\": {},\n \"approval_status\": \"{}\",\n \"external_action_count\": 1,\n \"final_state_has_pull_request\": {}\n}}",
151 run_id,
152 approvals.len(),
153 approvals.first().map(|row| row.status.as_str()).unwrap_or(""),
154 runtime
155 .store
156 .final_state(&run_id)?
157 .contains_key("pull_request")
158 );
159 Ok(())
160}Sourcepub fn add_tool(&mut self, descriptor: State, handler: MCPCall)
pub fn add_tool(&mut self, descriptor: State, handler: MCPCall)
Examples found in repository?
examples/mcp_governance.rs (lines 37-79)
33fn main() -> agentledger::Result<()> {
34 let mut runtime = Runtime::new();
35 runtime.set_sandbox(Box::new(DemoSandboxExecutor));
36 let mut server = InMemoryMCPToolServer::new();
37 server.add_tool(
38 state(&[
39 ("name", "mcp.github.create_pr".into()),
40 (
41 "inputSchema",
42 Value::Object(state(&[
43 ("type", "object".into()),
44 (
45 "required",
46 Value::Array(vec![Value::String("title".to_string())]),
47 ),
48 (
49 "properties",
50 Value::Object(state(&[(
51 "title",
52 Value::Object(state(&[
53 ("type", "string".into()),
54 ("minLength", 1_i64.into()),
55 ])),
56 )])),
57 ),
58 ])),
59 ),
60 (
61 "annotations",
62 Value::Object(state(&[
63 ("side_effect", "external_write".into()),
64 ("risk_level", "high".into()),
65 ("idempotency_required", true.into()),
66 ("approval_required", true.into()),
67 ("sandbox_required", true.into()),
68 (
69 "sandbox_policy",
70 Value::Object(state(&[
71 ("network", "deny".into()),
72 ("filesystem", "read-only".into()),
73 ])),
74 ),
75 ])),
76 ),
77 ]),
78 create_pr,
79 );
80 let adapter = MCPToolAdapter { client_call: create_pr };
81 for descriptor in server.list_tools() {
82 runtime.register_tool(adapter.tool_spec_from_descriptor(&descriptor));
83 }
84
85 let (run_id, _) = runtime.create_run(State::new());
86 let first_claim = runtime.store.claim_step("worker-before-approval", &run_id, 60.0)?;
87 let first_ctx = AgentContext {
88 run_id: run_id.clone(),
89 session_id: first_claim.session_id.clone(),
90 step_id: first_claim.step_id.clone(),
91 agent_role: "MCPAgent".to_string(),
92 lease_token: first_claim.lease_token.clone(),
93 attempt: first_claim.attempt,
94 state_version: first_claim.state_version,
95 pending_patch: State::new(),
96 };
97 let first = runtime.call_tool(
98 &first_ctx,
99 "mcp.github.create_pr",
100 state(&[
101 ("title", "Update runtime docs".into()),
102 ("_logical_operation", "docs-pr".into()),
103 ]),
104 );
105 let approval_id = first
106 .unwrap_err()
107 .0
108 .trim_start_matches("approval required:")
109 .to_string();
110 runtime.store.mark_waiting_human(
111 &run_id,
112 &first_ctx.step_id,
113 "approval required for tool mcp.github.create_pr",
114 &approval_id,
115 );
116 runtime
117 .store
118 .approve_request(&approval_id, "maintainer", "demo approval")?;
119
120 let second_claim = runtime.store.claim_step("worker-after-approval", &run_id, 60.0)?;
121 let mut second_ctx = AgentContext {
122 run_id: run_id.clone(),
123 session_id: second_claim.session_id.clone(),
124 step_id: second_claim.step_id.clone(),
125 agent_role: "MCPAgent".to_string(),
126 lease_token: second_claim.lease_token.clone(),
127 attempt: second_claim.attempt,
128 state_version: second_claim.state_version,
129 pending_patch: State::new(),
130 };
131 let result = runtime.call_tool(
132 &second_ctx,
133 "mcp.github.create_pr",
134 state(&[
135 ("title", "Update runtime docs".into()),
136 ("_logical_operation", "docs-pr".into()),
137 ]),
138 )?;
139 second_ctx.write_state("pull_request", result);
140 runtime.store.commit_state_patch(
141 &run_id,
142 &second_ctx.step_id,
143 &second_ctx.lease_token,
144 second_ctx.state_version,
145 second_ctx.pending_patch,
146 )?;
147
148 let approvals = runtime.store.approval_requests(&run_id);
149 println!(
150 "{{\n \"run_id\": \"{}\",\n \"first_attempt_waited_for_approval\": true,\n \"second_attempt_ok\": true,\n \"approval_count\": {},\n \"approval_status\": \"{}\",\n \"external_action_count\": 1,\n \"final_state_has_pull_request\": {}\n}}",
151 run_id,
152 approvals.len(),
153 approvals.first().map(|row| row.status.as_str()).unwrap_or(""),
154 runtime
155 .store
156 .final_state(&run_id)?
157 .contains_key("pull_request")
158 );
159 Ok(())
160}Sourcepub fn list_tools(&self) -> Vec<State> ⓘ
pub fn list_tools(&self) -> Vec<State> ⓘ
Examples found in repository?
examples/mcp_governance.rs (line 81)
33fn main() -> agentledger::Result<()> {
34 let mut runtime = Runtime::new();
35 runtime.set_sandbox(Box::new(DemoSandboxExecutor));
36 let mut server = InMemoryMCPToolServer::new();
37 server.add_tool(
38 state(&[
39 ("name", "mcp.github.create_pr".into()),
40 (
41 "inputSchema",
42 Value::Object(state(&[
43 ("type", "object".into()),
44 (
45 "required",
46 Value::Array(vec![Value::String("title".to_string())]),
47 ),
48 (
49 "properties",
50 Value::Object(state(&[(
51 "title",
52 Value::Object(state(&[
53 ("type", "string".into()),
54 ("minLength", 1_i64.into()),
55 ])),
56 )])),
57 ),
58 ])),
59 ),
60 (
61 "annotations",
62 Value::Object(state(&[
63 ("side_effect", "external_write".into()),
64 ("risk_level", "high".into()),
65 ("idempotency_required", true.into()),
66 ("approval_required", true.into()),
67 ("sandbox_required", true.into()),
68 (
69 "sandbox_policy",
70 Value::Object(state(&[
71 ("network", "deny".into()),
72 ("filesystem", "read-only".into()),
73 ])),
74 ),
75 ])),
76 ),
77 ]),
78 create_pr,
79 );
80 let adapter = MCPToolAdapter { client_call: create_pr };
81 for descriptor in server.list_tools() {
82 runtime.register_tool(adapter.tool_spec_from_descriptor(&descriptor));
83 }
84
85 let (run_id, _) = runtime.create_run(State::new());
86 let first_claim = runtime.store.claim_step("worker-before-approval", &run_id, 60.0)?;
87 let first_ctx = AgentContext {
88 run_id: run_id.clone(),
89 session_id: first_claim.session_id.clone(),
90 step_id: first_claim.step_id.clone(),
91 agent_role: "MCPAgent".to_string(),
92 lease_token: first_claim.lease_token.clone(),
93 attempt: first_claim.attempt,
94 state_version: first_claim.state_version,
95 pending_patch: State::new(),
96 };
97 let first = runtime.call_tool(
98 &first_ctx,
99 "mcp.github.create_pr",
100 state(&[
101 ("title", "Update runtime docs".into()),
102 ("_logical_operation", "docs-pr".into()),
103 ]),
104 );
105 let approval_id = first
106 .unwrap_err()
107 .0
108 .trim_start_matches("approval required:")
109 .to_string();
110 runtime.store.mark_waiting_human(
111 &run_id,
112 &first_ctx.step_id,
113 "approval required for tool mcp.github.create_pr",
114 &approval_id,
115 );
116 runtime
117 .store
118 .approve_request(&approval_id, "maintainer", "demo approval")?;
119
120 let second_claim = runtime.store.claim_step("worker-after-approval", &run_id, 60.0)?;
121 let mut second_ctx = AgentContext {
122 run_id: run_id.clone(),
123 session_id: second_claim.session_id.clone(),
124 step_id: second_claim.step_id.clone(),
125 agent_role: "MCPAgent".to_string(),
126 lease_token: second_claim.lease_token.clone(),
127 attempt: second_claim.attempt,
128 state_version: second_claim.state_version,
129 pending_patch: State::new(),
130 };
131 let result = runtime.call_tool(
132 &second_ctx,
133 "mcp.github.create_pr",
134 state(&[
135 ("title", "Update runtime docs".into()),
136 ("_logical_operation", "docs-pr".into()),
137 ]),
138 )?;
139 second_ctx.write_state("pull_request", result);
140 runtime.store.commit_state_patch(
141 &run_id,
142 &second_ctx.step_id,
143 &second_ctx.lease_token,
144 second_ctx.state_version,
145 second_ctx.pending_patch,
146 )?;
147
148 let approvals = runtime.store.approval_requests(&run_id);
149 println!(
150 "{{\n \"run_id\": \"{}\",\n \"first_attempt_waited_for_approval\": true,\n \"second_attempt_ok\": true,\n \"approval_count\": {},\n \"approval_status\": \"{}\",\n \"external_action_count\": 1,\n \"final_state_has_pull_request\": {}\n}}",
151 run_id,
152 approvals.len(),
153 approvals.first().map(|row| row.status.as_str()).unwrap_or(""),
154 runtime
155 .store
156 .final_state(&run_id)?
157 .contains_key("pull_request")
158 );
159 Ok(())
160}pub fn call_tool(&self, name: &str, args: State) -> Result<Value>
Auto Trait Implementations§
impl Freeze for InMemoryMCPToolServer
impl RefUnwindSafe for InMemoryMCPToolServer
impl Send for InMemoryMCPToolServer
impl Sync for InMemoryMCPToolServer
impl Unpin for InMemoryMCPToolServer
impl UnsafeUnpin for InMemoryMCPToolServer
impl UnwindSafe for InMemoryMCPToolServer
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more