forked from 1b-agent/fieldcraft-upstream
MCP server: modelcraft-cli mcp (headless or bridged), read/write roots, end-to-end analysis over MCP (#48)
* io: read and write roots that confine an automation client's file access Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * engine: every file a command reads or writes is checked against the session's roots Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * engine: headless pictures of a session (model, geometry, deformed shape and contours) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * mcp: MCP server over stdio with headless and connected backends, roots and caps Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * cli: modelcraft-cli mcp [--connect ADDR | --headless] with automation read and write roots Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * mcp: end-to-end analysis of a corpus part over MCP (open, tet mesh, define, solve, probe, render) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * docs: MCP server (docs/mcp.md), Claude Code setup, roots; architecture, README, roadmap, attribution Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm --------- Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
29 files changed
+2405
-49
No files matched your search
@@ -18,6 +18,7 @@ pub mod cmd;
|
||||
pub mod history;
|
||||
pub mod results;
|
||||
pub mod sample;
|
||||
pub mod view;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
@@ -174,13 +175,17 @@ pub struct Session {
|
||||
pub results_view: Option<results::ResultsView>,
|
||||
/// The default work caps of commands; a file replacing the session keeps them.
|
||||
pub limits: Limits,
|
||||
/// The folders commands may read and write files in (an automation client's roots,
|
||||
/// docs/mcp.md); unconfined by default. A file replacing the session keeps them.
|
||||
pub file_access: modelcraft_io::roots::Roots,
|
||||
}
|
||||
|
||||
impl Session {
|
||||
/// Run a command. On an error or a panic the model, the design and the surfaces are left as
|
||||
/// they were.
|
||||
pub fn execute(&mut self, id: &str, params: &Value) -> Result<Value> {
|
||||
let spec = find_command(id).ok_or_else(|| EngineError::UnknownCommand(id.to_string()))?;
|
||||
// An id from hostile input is not echoed in full.
|
||||
let spec = find_command(id).ok_or_else(|| EngineError::UnknownCommand(id.chars().take(100).collect()))?;
|
||||
// Session commands (open, save, undo, redo) change the session only in their last step,
|
||||
// after everything that can fail, so they need no copy of the model to restore.
|
||||
let before = (spec.kind == CommandKind::Model).then(|| self.snapshot());
|
||||
@@ -255,6 +260,15 @@ impl Session {
|
||||
self.results.insert(result.step().to_string(), (self.revision, Arc::new(result)));
|
||||
}
|
||||
|
||||
/// The path to use for `access` to the file at `path`, checked against [`Session::file_access`].
|
||||
pub fn checked_path(&self, path: &str, access: modelcraft_io::roots::Access) -> Result<String> {
|
||||
let checked = self.file_access.check(std::path::Path::new(path), access)?;
|
||||
match checked.to_str() {
|
||||
Some(p) => Ok(p.to_string()),
|
||||
None => Err(EngineError::Params(format!("`{path}` resolves to a path that is not valid UTF-8"))),
|
||||
}
|
||||
}
|
||||
|
||||
/// The current state is what `path` now holds.
|
||||
pub(crate) fn mark_saved(&mut self, path: String) {
|
||||
self.path = Some(path);
|
||||
|
||||
Reference in new issue
Block a user