The
Mission
We
had
a
few
goals
in
mind
when
creating
this
project.
Ⅰ
AI agents are powerful generative forces, but lack the ability to execute...
Fabelis bridges that gap providing first-class MCP servers allowing remote tool calling. Post a tweet by prompting an agent!
AI agents are powerful generative forces, but lack the ability to execute...
Fabelis bridges that gap providing first-class MCP servers allowing remote tool calling. Post a tweet by prompting an agent!
Ⅱ
We build RIG, RIG builds us...
LLM applications need strong efficient backbones. Our framework is no exception.
We build RIG, RIG builds us...
LLM applications need strong efficient backbones. Our framework is no exception.
Ⅲ
With the modularity provided in this repo, anyone can contribute. We provide Interfaces and Guides to help you get started. Check out our social platforms to view any bounties or challenges related to OS contributions!
With the modularity provided in this repo, anyone can contribute. We provide Interfaces and Guides to help you get started. Check out our social platforms to view any bounties or challenges related to OS contributions!
What's
MCP
?
The
Model
Context
Protocol
is
the
API
Layer
for
Agents
Communicate with remote tools on demand
Fetch remote data and resources
Leverage established prompt templating
Our
Resources
Look
at
what
we
have
to
offer.
Feel
free
to
contribute.
The
Tech
You
get
it?
Come
on
now,
lets
see
what
it
can
do!
1pub async fn start(&mut self) {
2 info!("[TWITTER] Starting client with 15s delay...");
3 let (sender, mut receiver) = mpsc::channel(3);
4
5 let post_sender = sender.clone();
6 let post_config = self.config.clone();
7 tokio::spawn(async move {
8 sleep(std::time::Duration::from_secs(15)).await;
9 loop {
10 if post_sender.send(Action::Post()).await.is_err() {
11 break;
12 }
13
14 let delay = rand::thread_rng()
15 .gen_range(post_config.post_delay[0]..=post_config.post_delay[1]);
16 info!("[TWITTER][POST] sleeping for {} minutes", delay);
17 sleep(std::time::Duration::from_secs(u64::from(delay) * 60)).await;
18 }
19 });
20
21 let reply_sender = sender.clone();
22 let reply_config = self.config.clone();
23 tokio::spawn(async move {
24 sleep(std::time::Duration::from_secs(15)).await;
25 loop {
26 if reply_sender.send(Action::Reply()).await.is_err() {
27 break;
28 }
29
30 let delay = rand::thread_rng()
31 .gen_range(reply_config.reply_delay[0]..=reply_config.reply_delay[1]);
32 info!("[TWITTER][REPLY] sleeping for {} minutes", delay);
33 sleep(std::time::Duration::from_secs(u64::from(delay) * 60)).await;
34 }
35 });
36
37 while let Some(action) = receiver.recv().await {
38 match action {
39 Action::Post() => {
40 info!("[TWITTER][POST] Executing...");
41 let topic = self
42 .character
43 .choose_random_traits(crate::core::CharacterTrait::Topics, 1);
44
45 self.search(&topic).await;
46
47 sleep(std::time::Duration::from_secs(
48 u64::from(self.config.search_delay) * 60,
49 ))
50 .await;
51
52 self.post(topic).await;
53 }
54 Action::Reply() => info!("[TWITTER][REPLY] Executing..."),
55 }
56 sleep(std::time::Duration::from_secs(u64::from(self.config.delay))).await;
57 }
58 }
Click Here
Easily configure your own FABELIS agent instance using our examples and quick start guides. Fork our repository and get started in under 5 minutes.
1pub async fn start(&mut self) {
2 info!("[TWITTER] Starting client with 15s delay...");
3 let (sender, mut receiver) = mpsc::channel(3);
4
5 let post_sender = sender.clone();
6 let post_config = self.config.clone();
7 tokio::spawn(async move {
8 sleep(std::time::Duration::from_secs(15)).await;
9 loop {
10 if post_sender.send(Action::Post()).await.is_err() {
11 break;
12 }
13
14 let delay = rand::thread_rng()
15 .gen_range(post_config.post_delay[0]..=post_config.post_delay[1]);
16 info!("[TWITTER][POST] sleeping for {} minutes", delay);
17 sleep(std::time::Duration::from_secs(u64::from(delay) * 60)).await;
18 }
19 });
20
21 let reply_sender = sender.clone();
22 let reply_config = self.config.clone();
23 tokio::spawn(async move {
24 sleep(std::time::Duration::from_secs(15)).await;
25 loop {
26 if reply_sender.send(Action::Reply()).await.is_err() {
27 break;
28 }
29
30 let delay = rand::thread_rng()
31 .gen_range(reply_config.reply_delay[0]..=reply_config.reply_delay[1]);
32 info!("[TWITTER][REPLY] sleeping for {} minutes", delay);
33 sleep(std::time::Duration::from_secs(u64::from(delay) * 60)).await;
34 }
35 });
36
37 while let Some(action) = receiver.recv().await {
38 match action {
39 Action::Post() => {
40 info!("[TWITTER][POST] Executing...");
41 let topic = self
42 .character
43 .choose_random_traits(crate::core::CharacterTrait::Topics, 1);
44
45 self.search(&topic).await;
46
47 sleep(std::time::Duration::from_secs(
48 u64::from(self.config.search_delay) * 60,
49 ))
50 .await;
51
52 self.post(topic).await;
53 }
54 Action::Reply() => info!("[TWITTER][REPLY] Executing..."),
55 }
56 sleep(std::time::Duration::from_secs(u64::from(self.config.delay))).await;
57 }
58 }
Easily configure your own FABELIS agent instance using our examples and quick start guides. Fork our repository and get started in under 5 minutes.
Click Here
1use dotenv::dotenv;
2use mcp_core::{
3 client::Client,
4 transport::{ClientSseTransport, Transport},
5 types::Implementation,
6};
7use std::{env, sync::Arc};
8
9use mcp_rig::{completion::Prompt, providers};
10
11const DISCORD_SERVER_URL: &str = "https://discord-mcp.fabelis.ai";
12const TWITTER_SERVER_URL: &str = "https://twitter-mcp.fabelis.ai";
13
14#[tokio::main]
15async fn main() -> Result<(), anyhow::Error> {
16 tracing_subscriber::fmt().init();
17
18 dotenv().ok();
19
20 let transport = ClientSseTransport::builder(TWITTER_SERVER_URL.to_string()).build();
21 transport.open().await?;
22
23 let mcp_client = Arc::new(
24 Client::builder(transport)
25 .with_secure_value(
26 "twitter_api_key",
27 mcp_core::client::SecureValue::Env("TWITTER_API_KEY".to_string()),
28 )
29 .with_secure_value(
30 "twitter_api_secret",
31 mcp_core::client::SecureValue::Env("TWITTER_API_SECRET".to_string()),
32 )
33 .with_secure_value(
34 "twitter_access_token",
35 mcp_core::client::SecureValue::Env("TWITTER_ACCESS_TOKEN".to_string()),
36 )
37 .with_secure_value(
38 "twitter_access_token_secret",
39 mcp_core::client::SecureValue::Env("TWITTER_ACCESS_TOKEN_SECRET".to_string()),
40 )
41 .use_strict()
42 .build(),
43 );
44 let mcp_client_clone = mcp_client.clone();
45 tokio::spawn(async move { mcp_client_clone.start().await });
46
47 let init_res = mcp_client
48 .initialize(Implementation {
49 name: "mcp-client".to_string(),
50 version: "0.1.0".to_string(),
51 })
52 .await?;
53 println!("Initialized: {:?}", init_res);
54
55 let tools_list_res = mcp_client.list_tools(None, None).await?;
56 println!("Tools: {:?}", tools_list_res);
57
58 tracing::info!("Running RIG example");
59
60 let openai_client = providers::openai::Client::new(
61 &env::var("OPENAI_API_KEY").expect("OPENAI_API_KEY not set"),
62 );
63
64 let mut agent_builder = openai_client.agent("gpt-4o")
65 // Use preamble to allow for secure values to be used in the tool call
66 .preamble("If a tool says fields can use a null value do not ask the user for those values and default them to an empty strings because the MCP Client will add them automatically.");
67
68 // Add MCP tools to the agent
69 agent_builder = tools_list_res
70 .tools
71 .into_iter()
72 .fold(agent_builder, |builder, tool| {
73 builder.mcp_tool(tool, mcp_client.clone())
74 });
75 let agent = agent_builder.build();
76
77 let response = agent.prompt("Post 'hello' on twitter").await?;
78 tracing::info!("Agent response: {:?}", response);
79
80 Ok(())
81}
Click Here
Our signature product offering are our Rust MCP servers. Fully compatible with both RIG and any other MCP client of your choice, out of the box.
1use dotenv::dotenv;
2use mcp_core::{
3 client::Client,
4 transport::{ClientSseTransport, Transport},
5 types::Implementation,
6};
7use std::{env, sync::Arc};
8
9use mcp_rig::{completion::Prompt, providers};
10
11const DISCORD_SERVER_URL: &str = "https://discord-mcp.fabelis.ai";
12const TWITTER_SERVER_URL: &str = "https://twitter-mcp.fabelis.ai";
13
14#[tokio::main]
15async fn main() -> Result<(), anyhow::Error> {
16 tracing_subscriber::fmt().init();
17
18 dotenv().ok();
19
20 let transport = ClientSseTransport::builder(TWITTER_SERVER_URL.to_string()).build();
21 transport.open().await?;
22
23 let mcp_client = Arc::new(
24 Client::builder(transport)
25 .with_secure_value(
26 "twitter_api_key",
27 mcp_core::client::SecureValue::Env("TWITTER_API_KEY".to_string()),
28 )
29 .with_secure_value(
30 "twitter_api_secret",
31 mcp_core::client::SecureValue::Env("TWITTER_API_SECRET".to_string()),
32 )
33 .with_secure_value(
34 "twitter_access_token",
35 mcp_core::client::SecureValue::Env("TWITTER_ACCESS_TOKEN".to_string()),
36 )
37 .with_secure_value(
38 "twitter_access_token_secret",
39 mcp_core::client::SecureValue::Env("TWITTER_ACCESS_TOKEN_SECRET".to_string()),
40 )
41 .use_strict()
42 .build(),
43 );
44 let mcp_client_clone = mcp_client.clone();
45 tokio::spawn(async move { mcp_client_clone.start().await });
46
47 let init_res = mcp_client
48 .initialize(Implementation {
49 name: "mcp-client".to_string(),
50 version: "0.1.0".to_string(),
51 })
52 .await?;
53 println!("Initialized: {:?}", init_res);
54
55 let tools_list_res = mcp_client.list_tools(None, None).await?;
56 println!("Tools: {:?}", tools_list_res);
57
58 tracing::info!("Running RIG example");
59
60 let openai_client = providers::openai::Client::new(
61 &env::var("OPENAI_API_KEY").expect("OPENAI_API_KEY not set"),
62 );
63
64 let mut agent_builder = openai_client.agent("gpt-4o")
65 // Use preamble to allow for secure values to be used in the tool call
66 .preamble("If a tool says fields can use a null value do not ask the user for those values and default them to an empty strings because the MCP Client will add them automatically.");
67
68 // Add MCP tools to the agent
69 agent_builder = tools_list_res
70 .tools
71 .into_iter()
72 .fold(agent_builder, |builder, tool| {
73 builder.mcp_tool(tool, mcp_client.clone())
74 });
75 let agent = agent_builder.build();
76
77 let response = agent.prompt("Post 'hello' on twitter").await?;
78 tracing::info!("Agent response: {:?}", response);
79
80 Ok(())
81}
Our signature product offering are our Rust MCP servers. Fully compatible with both RIG and any other MCP client of your choice, out of the box
Click Here
Click Here
FABELIS constantly strives for new innovations. You can view the latest updates of our roadmap and our future on our Social Platforms.
FABELIS constantly strives for new innovations. You can view the latest updates of our roadmap and our future on our Social Platforms.
Click Here
"MODULARITY IS KING"
FABELIS.AI 2025