use std::net::SocketAddr;
use std::sync::Arc;
use pmcp::server::streamable_http_server::{StreamableHttpServer, StreamableHttpServerConfig};
use pmcp::Server;
use pmcp_server_toolkit::sql::{SqlConnector, SqliteConnector};
use pmcp_server_toolkit::{ServerBuilderExt, ServerConfig, StaticResourceHandler};
use tokio::sync::Mutex;
use tokio::task::JoinHandle;
const FIXTURES_DIR: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/examples/fixtures");
async fn serve(server: Server) -> Result<(SocketAddr, JoinHandle<()>), Box<dyn std::error::Error>> {
let shared = Arc::new(Mutex::new(server));
let cfg = StreamableHttpServerConfig::default();
Ok(
StreamableHttpServer::with_config("127.0.0.1:0".parse()?, shared, cfg)
.start()
.await?,
)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
std::env::set_var("PMCP_ASSETS_DIR", FIXTURES_DIR); let cfg = ServerConfig::from_toml_strict_validated(&pmcp::assets::load_string("config.toml")?)?;
let conn = SqliteConnector::open(pmcp_server_toolkit::demo_db_path().as_ref())?; conn.execute_batch(&pmcp::assets::load_string("schema.sql")?)
.await?; let conn: Arc<dyn SqlConnector> = Arc::new(conn); let builder = Server::builder()
.name(&cfg.server.name)
.version(&cfg.server.version);
let builder = builder.try_tools_from_config_with_connector(&cfg, conn.clone())?;
let builder = builder.try_code_mode_from_config_with_connector(&cfg, conn)?;
let server = builder
.resources_arc(Arc::new(StaticResourceHandler::from(&cfg)))
.build()?;
let (addr, handle) = serve(server).await?;
println!("PMCP_SQL_SERVER_ADDR=http://{addr}"); handle.await?;
Ok(())
}