Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosfreeCodeCamp.org: TimescaleDB Course – PostgreSQL for Time-Series Data(23.09.2026 um 12:30 Uhr)
Windows Tipps & SecurityAndroid 17: Rollout auf Samsung-Galaxy-Smartphones verzögert sich(23.09.2026 um 11:42 Uhr)
Unix & Linux ServerUSN-8733-2: Gzip vulnerabilities(22.09.2026 um 18:04 Uhr)
Sichere ProgrammierungHow to Build Custom PowerPoint Add-Ins for Enterprise Teams(23.09.2026 um 11:25 Uhr)
Sichere ProgrammierungSearch Google Jobs in Real-Time with Go and SerpApi 🚀(23.09.2026 um 12:13 Uhr)
Sichere ProgrammierungA Psychological State is a Coefficient Vector(23.09.2026 um 12:16 Uhr)
YouTube Security VideosfreeCodeCamp.org: TimescaleDB Course – PostgreSQL for Time-Series Data(23.09.2026 um 12:30 Uhr)
Windows Tipps & SecurityAndroid 17: Rollout auf Samsung-Galaxy-Smartphones verzögert sich(23.09.2026 um 11:42 Uhr)
Unix & Linux ServerUSN-8733-2: Gzip vulnerabilities(22.09.2026 um 18:04 Uhr)
Sichere ProgrammierungHow to Build Custom PowerPoint Add-Ins for Enterprise Teams(23.09.2026 um 11:25 Uhr)
Sichere ProgrammierungSearch Google Jobs in Real-Time with Go and SerpApi 🚀(23.09.2026 um 12:13 Uhr)
Sichere ProgrammierungA Psychological State is a Coefficient Vector(23.09.2026 um 12:16 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Build One AI Tool Server, Call It From Three Different Agents (MCP Explained)

Have you ever wanted to give an AI assistant a new ability — like generating images — and have that ability work in any AI tool you use, not just one? That's exactly what this project does, and the magic ingredient is the Model Context Pro…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

Have you ever wanted to give an AI assistant a new ability — like generating images — and have that ability work in any AI tool you use, not just one?



That's exactly what this project does, and the magic ingredient is the Model Context Protocol (MCP). In this article we'll walk through a real, working repo where one small Python server gives image-generation superpowers to three completely different programs:




  1. 🖥️ Claude Code (Anthropic's AI coding assistant)

  2. 🐍 A Google ADK agent written in Python

  3. 🦀 A Rust command-line app



None of them share a single line of code. Let's see how.









🤔 First: what is MCP?



Think of MCP as USB-C for AI tools.



Before USB-C, every device needed its own special cable. Before MCP, every AI app needed its own special plugin format — a ChatGPT plugin didn't work in Claude, a Claude tool didn't work in your Python agent, and so on.



MCP fixes this with a simple split:




  • An MCP server is a small program that offers tools. Each tool has a name, a description, and typed parameters — like a function signature the AI can read.

  • An MCP client lives inside an AI app. It asks the server "what tools do you have?", shows them to the AI model, and forwards the model's tool calls back to the server.



The two sides talk JSON messages. The simplest way they connect is called stdio: the client just launches the server as a child process and they chat over standard input/output — the same pipes you use when you run echo hi | grep h.




💡 Fun consequence: because stdout is the communication channel, an MCP server must never print() to it. Our server logs to stderr instead. One stray print statement would garble the protocol!







🤖 And what is an "agent"?



An agent is an AI model in a loop with tools: the model reads your request, decides a tool would help, calls it, reads the result, and keeps going until the job is done. The AI is the brain; MCP tools are the hands.









🗺️ The project at a glance



Here's the repo layout:




nb2lite-agent-claude/
├── MCP/ ← the star: an MCP server wrapping Gemini's image model
│ └── server.py
├── python/ ← consumer 1: a Google ADK agent
├── rust/ ← consumer 2: a Rust CLI client
└── .mcp.json ← consumer 3: config that plugs the server into Claude Code






And here's how the pieces connect:




 Claude Code  ──┐
ADK agent ──┼── MCP over stdio ──► MCP/server.py ──► Gemini image API
Rust CLI ──┘ │

images/ folder
(your generated PNGs)






Three arrows in, one server, one API out. The Gemini-specific code exists in exactly one file.









🎨 The server: 4 tools in ~300 lines



The server is built with FastMCP, which ships with the official mcp Python package. Writing a tool is as easy as decorating a function:




from mcp.server.fastmcp import FastMCP

mcp = FastMCP("NB2Lite Agent")

@mcp.tool()
def generate_image(
prompt: str, aspect_ratio: str = "1:1", thinking_level: str = "low"
) -> str:
"""Generates a new image from a text prompt."""
...






That's it. FastMCP reads the function signature and docstring and automatically tells every connected AI: "there's a tool called generate_image, here's what it does, here are its parameters." Your code is the documentation the AI sees.



The server exposes four tools:




























Tool What it does
generate_image Text prompt → brand-new image
edit_image "Change X in the image we just made"
edit_local_image Edit an image file from your disk
get_help The server describes its own config and tools


Under the hood, they all call Google's gemini-3.1-flash-lite-image model — a fast image model — through something called the Interactions API.






🔁 The cool part: edits that remember



Most image APIs are goldfish: every request starts from zero. The Interactions API is different — it's stateful. Every generation returns an interaction_id, and you can pass that ID back to continue the session:




interaction = ai_client.interactions.create(
model=MODEL_NAME,
previous_interaction_id=previous_interaction_id, # 👈 "continue from here"
input=edit_prompt,
response_format={"type": "image"},
store=True, # 👈 remember this interaction on Google's side
)






In practice, a conversation looks like this:





  1. You: "Generate a cyberpunk ramen kitchen, 16:9"


  2. Agent calls generate_image(...) → gets back "Saved to gen_...png • Interaction ID: int_abc"


  3. You: "Nice — add a neon sign that says RAMEN"


  4. Agent calls edit_image(previous_interaction_id="int_abc", edit_prompt="add a neon RAMEN sign")

  5. The model edits that exact image, keeping the style and details consistent 🎉



Notice who remembers what: Google's servers store the image session, and the agent's conversation memory holds the ID. The MCP server itself stays stateless — you can restart it anytime.






📦 Why the tools return file paths, not images



A tool could send the image bytes back to the AI. This server deliberately doesn't — it saves the file to disk and returns a short message:




🟢 Image successfully saved!
• Saved to: /home/you/images/gen_1780123456_a3b2c1d0.png
• Interaction ID: int_abc






Two beginner-friendly lessons hide in here:





  • Token economy. A base64-encoded PNG is huge. Stuffing it into the AI's context would waste thousands of tokens for nothing — the AI can't do much with raw pixels, but it can absolutely tell you a file path.


  • Friendly errors. Every tool catches exceptions and returns a readable 🔴 Image generation failed: ... string instead of crashing. The AI reads the error and can fix its own mistake (wrong aspect ratio? it'll retry with a valid one).









🔌 Consumer 1: Claude Code (zero code!)



Plugging the server into Claude Code takes only a config file, .mcp.json:




{
"mcpServers": {
"nb2lite-agent": {
"type": "stdio",
"command": "python3",
"args": ["/path/to/MCP/server.py"],
"env": { "GEMINI_API_KEY": "${GEMINI_API_KEY}" }
}
}
}






Claude Code launches the server, discovers the four tools, and from then on you can just type "generate a 16:9 image of a mountain sunrise" in your coding session.






🐍 Consumer 2: a Google ADK agent



The Agent Development Kit (ADK) is Google's framework for building your own agents. Its MCPToolset does all the MCP plumbing — spawn the server, do the handshake, convert every discovered tool into something the LLM can call:




root_agent = LlmAgent(
name="nb2lite_adk_agent",
model="gemini-2.5-flash",
instruction="...remember the most recent Interaction ID and pass it "
"as previous_interaction_id for follow-up edits...",
tools=[
MCPToolset(
connection_params=StdioConnectionParams(
server_params=StdioServerParameters(
command="python3",
args=[str(MCP_SERVER)],
),
),
)
],
)






Two things worth noticing:




  • We never define generate_image in this file. The toolset imports the tools over the protocol at startup.

  • The instruction explicitly tells the LLM to track interaction IDs. The protocol carries the ID; the LLM's memory keeps it.



Run it with adk run nb2lite_adk_agent for a chat in your terminal, or adk web for a browser UI.






🦀 Consumer 3: a Rust CLI



To prove the "any language" claim, the repo includes a Rust client using rmcp, the official Rust MCP SDK. It spawns the same Python server as a child process:




let service = ()
.serve(TokioChildProcess::new(Command::new("python3").configure(
|cmd| { cmd.arg(&server); },
))?)
.await?;

let result = service
.call_tool(CallToolRequestParam {
name: "generate_image".into(),
arguments: json!({ "prompt": prompt, "aspect_ratio": "16:9" })
.as_object().cloned(),
})
.await?;






There's no AI model in this binary at all — it's a plain program calling the tools directly:




cargo run -- tools                                          # list the tools
cargo run -- generate "a cyberpunk ramen kitchen" 16:9 high # make an image
cargo run -- edit int_abc123 "add a neon RAMEN sign" # refine it






That's a nice mental model to end on: an MCP tool call is just a function call over a pipe. An LLM can make it, and so can your shell script.









🧠 The takeaway



Without MCP, supporting these three consumers means three integrations: a Claude-specific setup, an ADK wrapper, and a Rust port of the Gemini client. Three places to update every time the API changes.



With MCP, the capability lives in one file, and each consumer is ~30 lines of config or boilerplate. Adding a fourth consumer tomorrow — LangChain, an editor plugin, whatever — costs about the same.



Write the tool once. Let every agent call it.






🚀 Try it yourself



The server is published as a ready-to-run Docker image — you don't need the repo at all. Point any MCP client at it (this is a .mcp.json for Claude Code):




{
"mcpServers": {
"nb2lite-agent": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "GEMINI_API_KEY",
"-v", "/absolute/path/to/images:/images",
"xbill9/nb2lite-mcp:latest"]
}
}
}






Set GEMINI_API_KEY in your environment, ask your agent to generate an image, and check your mounted images/ folder. (Remember: -i but never -t — a TTY corrupts the protocol stream!)



Questions about MCP, ADK, or the Rust side? Drop them in the comments! 👇

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Build One AI Tool Server, Call It From Three Different Agents (MCP Explained)

Thematisch verwandte Begriffe: Build, Tool, Server, Call · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-96258 | A vulnerability has been found in onSite internet GmbH Auktion NG Auktio…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick