<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ajit</title>
    <description>The latest articles on DEV Community by Ajit (@ajitnk2006).</description>
    <link>https://dev.to/ajitnk2006</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1214886%2F4def6a73-9fa4-4fa4-a91d-b4465bb62077.png</url>
      <title>DEV Community: Ajit</title>
      <link>https://dev.to/ajitnk2006</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ajitnk2006"/>
    <language>en</language>
    <item>
      <title>How I Track 44 New AWS Repos Per Week Automatically with EventBridge, Bedrock, and FAISS</title>
      <dc:creator>Ajit</dc:creator>
      <pubDate>Wed, 01 Apr 2026 09:38:28 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-i-track-44-new-aws-repos-per-week-automatically-with-eventbridge-bedrock-and-faiss-ke8</link>
      <guid>https://dev.to/aws-builders/how-i-track-44-new-aws-repos-per-week-automatically-with-eventbridge-bedrock-and-faiss-ke8</guid>
      <description>&lt;p&gt;AWS publishes new sample repos almost daily — reference architectures, agent patterns, CDK constructs, security blueprints — spread across 5 different GitHub organizations.&lt;/p&gt;

&lt;p&gt;Most developers never see them until weeks later.&lt;/p&gt;

&lt;p&gt;I built a system that catches them the same day. Here's how.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;AWS maintains 9,657+ repos across these orgs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;aws-samples&lt;/strong&gt; (8,044 repos)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;awslabs&lt;/strong&gt; (992 repos)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;aws-ia&lt;/strong&gt; (234 repos)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;aws-solutions&lt;/strong&gt; (153 repos)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;aws-solutions-library-samples&lt;/strong&gt; (234 repos)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When AWS publishes a new repo — say, a production-ready Bedrock AgentCore sample or a CDK construct for EKS — it's buried. GitHub search doesn't surface it. Google takes days to index it. By the time you find it, someone else already built on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Auto-Indexing Pipeline
&lt;/h2&gt;

&lt;p&gt;I built AWS Solution Finder with a twice-daily auto-indexing pipeline that detects and classifies new repos automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;EventBridge (cron: 2 AM + 2 PM UTC daily)&lt;br&gt;
   ↓&lt;br&gt;
5 separate rules (one per org)&lt;br&gt;
   ↓&lt;br&gt;
Indexer Lambda (Docker, Python 3.12, 3GB, 15-min timeout)&lt;br&gt;
   ↓&lt;br&gt;
For each org:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fetch ALL repos from GitHub API (paginated)&lt;/li&gt;
&lt;li&gt;Compare with master index in S3 → find NEW + REMOVED repos&lt;/li&gt;
&lt;li&gt;Classify new repos with Bedrock Nova Pro (22 metadata fields)&lt;/li&gt;
&lt;li&gt;Generate Titan Embed v2 embeddings (1024-dim)&lt;/li&gt;
&lt;li&gt;Incrementally update FAISS index&lt;/li&gt;
&lt;li&gt;Save to S3 + publish new Lambda version&lt;/li&gt;
&lt;li&gt;Write run record to DynamoDB&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The 22 Metadata Fields
&lt;/h3&gt;

&lt;p&gt;Every repo gets classified by Bedrock Nova Pro:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solution type, competency area, AWS services used&lt;/li&gt;
&lt;li&gt;Primary/secondary language, deployment tools&lt;/li&gt;
&lt;li&gt;Cost range, setup time, complexity&lt;/li&gt;
&lt;li&gt;Business value, target audience, freshness status&lt;/li&gt;
&lt;li&gt;Agentic capabilities (yes/no/partial)&lt;/li&gt;
&lt;li&gt;And more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what makes search actually useful — you're not just matching keywords, you're matching intent against structured metadata.&lt;/p&gt;

&lt;h3&gt;
  
  
  Safety Guards
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;If &amp;gt;50% of repos would be removed in a single run → &lt;strong&gt;blocked&lt;/strong&gt; (likely GitHub API error)&lt;/li&gt;
&lt;li&gt;If GitHub returns 0 repos → master index NOT updated&lt;/li&gt;
&lt;li&gt;Ghost repo detection: repos in FAISS but not on GitHub get cleaned up&lt;/li&gt;
&lt;li&gt;Rate limiting on GitHub API calls (1 sec between classifications)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The New Feature: "New Repos This Week"
&lt;/h2&gt;

&lt;p&gt;Today I shipped a badge on the search page showing repos added in the last 7 days:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🆕 &lt;strong&gt;44 new repos this week&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Grouped by org (aws-samples, awslabs, etc.)&lt;/li&gt;
&lt;li&gt;Direct GitHub links for each&lt;/li&gt;
&lt;li&gt;Rolling 7-day window, updated twice daily&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh4cr3c31z8h6jv2lg0wj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh4cr3c31z8h6jv2lg0wj.png" alt=" " width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftd49qdpmmfktkljorytc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftd49qdpmmfktkljorytc.png" alt=" " width="800" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gives users a reason to come back daily — not just when they need to search.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scheduling&lt;/td&gt;
&lt;td&gt;Amazon EventBridge (5 rules, twice daily)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Compute&lt;/td&gt;
&lt;td&gt;AWS Lambda (Docker, Python 3.12, 3GB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI Classification&lt;/td&gt;
&lt;td&gt;Amazon Bedrock Nova Pro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embeddings&lt;/td&gt;
&lt;td&gt;Amazon Bedrock Titan Embed v2 (1024-dim)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vector Search&lt;/td&gt;
&lt;td&gt;FAISS (IndexFlatL2, in-memory)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;Amazon S3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit Trail&lt;/td&gt;
&lt;td&gt;Amazon DynamoDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IaC&lt;/td&gt;
&lt;td&gt;AWS CDK (TypeScript)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Total cost for the indexing pipeline: almost nothing. The Lambda runs for ~5 minutes twice a day. Bedrock calls are only for NEW repos (not re-classifying existing ones).&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;The 🆕 badge is live now. Free to try — 3 searches without registration.&lt;/p&gt;

&lt;p&gt;→ &lt;a href="https://awssolutionfinder.solutions.cloudnestle.com/search?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=new-repos-feature" rel="noopener noreferrer"&gt;awssolutionfinder.solutions.cloudnestle.com/search&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What AWS repos have you discovered recently that more people should know about?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by Ajit NK — AWS Community Builder (Dev Tools). Building AI-powered developer tools at CloudNestle.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I Search 10,000+ AWS GitHub Repos in 10 Seconds</title>
      <dc:creator>Ajit</dc:creator>
      <pubDate>Tue, 31 Mar 2026 12:51:14 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-i-search-10000-aws-github-repos-in-10-seconds-4hi2</link>
      <guid>https://dev.to/aws-builders/how-i-search-10000-aws-github-repos-in-10-seconds-4hi2</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Every AWS developer knows this pain: you need a reference architecture or sample code, and you end up with 47 browser tabs open across GitHub, AWS docs, Stack Overflow, and random blog posts from 2019.&lt;/p&gt;

&lt;p&gt;GitHub search gives you 2,000 results with zero context. ChatGPT confidently hallucinates repos that don't exist. Stack Overflow answers are outdated.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built an AI-powered search engine that indexes 10,000+ repos from AWS's official GitHub organizations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;aws-samples&lt;/strong&gt;: 8,031 repos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;awslabs&lt;/strong&gt;: 993 repos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;aws-solutions-library-samples&lt;/strong&gt;: 315 repos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;aws-ia&lt;/strong&gt;: 234 repos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;aws-solutions&lt;/strong&gt;: 72 repos&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;p&gt;The search uses a hybrid approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;70% BM25&lt;/strong&gt; (keyword matching) — catches exact AWS service names&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;30% FAISS&lt;/strong&gt; (semantic vector search) — understands what you mean, not just what you type&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each repo is classified by Amazon Bedrock (Nova Pro) across &lt;strong&gt;22 metadata fields&lt;/strong&gt;: solution type, AWS services used, complexity, freshness, setup time estimate, and more.&lt;/p&gt;

&lt;p&gt;Auto-indexed twice daily via EventBridge — new AWS repos are searchable within 12 hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Amazon Bedrock (Nova Pro) for AI classification&lt;/li&gt;
&lt;li&gt;FAISS with Titan Embed v2 (1024-dim) for vector search&lt;/li&gt;
&lt;li&gt;AWS Lambda (Docker, Python 3.12)&lt;/li&gt;
&lt;li&gt;API Gateway&lt;/li&gt;
&lt;li&gt;DynamoDB for usage tracking&lt;/li&gt;
&lt;li&gt;CloudFront + S3 for frontend&lt;/li&gt;
&lt;li&gt;EventBridge for scheduled indexing&lt;/li&gt;
&lt;li&gt;AWS CDK (TypeScript) for infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Architecture Decisions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why hybrid search over pure vector?&lt;/strong&gt;&lt;br&gt;
AWS service names are precise — "Lambda" means something specific. Pure semantic search sometimes returns "serverless compute" results when you specifically want Lambda. BM25 catches exact matches, FAISS catches intent. The 70/30 split was tuned through testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why FAISS over OpenSearch?&lt;/strong&gt;&lt;br&gt;
Cost. OpenSearch Serverless has a minimum cost that runs 24/7. FAISS on Lambda + S3 costs under $6/month for the search component. For a bootstrapped product, that matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why 22 metadata fields?&lt;/strong&gt;&lt;br&gt;
Developers don't just want to find a repo — they want to know: Is it maintained? How complex is it? What AWS services does it use? How long will setup take? Nova Pro classifies each repo across all 22 fields automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Hybrid search beats pure vector for domain-specific queries&lt;/li&gt;
&lt;li&gt;FAISS on Lambda is surprisingly cost-effective&lt;/li&gt;
&lt;li&gt;The 22-field classification is what makes results actually useful — not just the search itself&lt;/li&gt;
&lt;li&gt;Auto-indexing twice daily keeps results fresh without manual work&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Free to use — 3 searches without registration, 10 per day with a free account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://awssolutionfinder.solutions.cloudnestle.com/search?utm_source=devto&amp;amp;utm_medium=blog&amp;amp;utm_campaign=launch" rel="noopener noreferrer"&gt;AWS Solution Finder&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Exploring ways to improve relevance scoring and add more metadata fields. If you've worked with FAISS or hybrid search, I'd love to hear your approach.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built solo by an AWS Community Builder. Questions? Drop a comment.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>devtools</category>
      <category>serverless</category>
    </item>
    <item>
      <title># Building a Mobile AI Assistant with Kiro CLI and the Agent Client Protocol</title>
      <dc:creator>Ajit</dc:creator>
      <pubDate>Tue, 24 Mar 2026 11:14:41 +0000</pubDate>
      <link>https://dev.to/aws-builders/-building-a-mobile-ai-assistant-with-kiro-cli-and-the-agent-client-protocol-258d</link>
      <guid>https://dev.to/aws-builders/-building-a-mobile-ai-assistant-with-kiro-cli-and-the-agent-client-protocol-258d</guid>
      <description>&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/mxfAifdPCJE"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;h2&gt;
  
  
  Situation
&lt;/h2&gt;

&lt;p&gt;AI coding assistants are powerful — but they're trapped. Locked inside your terminal or IDE. Step away from your desk and you lose access to your AI agent, your workspace context, your tools.&lt;/p&gt;

&lt;p&gt;I work across multiple environments — laptop, phone, sometimes just a quick check between meetings. My AI assistant (Kiro CLI) knows my codebase, has access to MCP tools (web search, AWS docs), and can read/write files. But only when I'm sitting at my terminal.&lt;/p&gt;

&lt;p&gt;The question: &lt;strong&gt;Can I take my AI agent mobile without rebuilding it from scratch?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Task
&lt;/h2&gt;

&lt;p&gt;Build a bridge that connects Kiro CLI to Telegram — so I can message my AI assistant from my phone and get the same capabilities as the terminal: file access, tool execution, MCP servers, streamed responses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constraints:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No modifications to Kiro CLI itself — use its public protocol&lt;/li&gt;
&lt;li&gt;Channel-agnostic architecture — Telegram today, Slack/Discord tomorrow&lt;/li&gt;
&lt;li&gt;Real tool access — not just a chatbot wrapper, but actual file reads, terminal commands, web search&lt;/li&gt;
&lt;li&gt;Production-ready — auth, error handling, message splitting, typing indicators&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Action
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Discovering ACP
&lt;/h3&gt;

&lt;p&gt;Kiro CLI implements the &lt;a href="https://agentclientprotocol.com" rel="noopener noreferrer"&gt;Agent Client Protocol (ACP)&lt;/a&gt; — an open standard for AI agent communication, similar to how LSP standardized language servers. It uses JSON-RPC 2.0 over stdio.&lt;/p&gt;

&lt;p&gt;This means any process that can spawn &lt;code&gt;kiro-cli acp&lt;/code&gt; and pipe JSON through stdin/stdout becomes an ACP client. Not just IDEs — anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8tivhhu73df8hekoyr40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8tivhhu73df8hekoyr40.png" alt="Architecture Diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Three layers, cleanly separated using the &lt;strong&gt;Adapter Pattern&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Telegram Adapter&lt;/strong&gt; — Auth, typing indicators, message splitting. Knows nothing about ACP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ACP Client&lt;/strong&gt; — JSON-RPC transport. Manages protocol lifecycle. Knows nothing about Telegram.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kiro CLI&lt;/strong&gt; — AI agent runtime. Model inference, tool execution, MCP servers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Swap Telegram for Slack by writing a new adapter. The ACP client stays identical.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing the ACP Handshake
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkiey53wvzvbb1pj8x30r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkiey53wvzvbb1pj8x30r.png" alt="Protocol Flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ACP has a clear lifecycle — initialize, create session, prompt, stream:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Step 1: Spawn Kiro CLI as ACP agent&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kiro-cli&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;acp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;--trust-all-tools&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;stdio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pipe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/path/to/workspace&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Step 2: Initialize — exchange capabilities&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;initialize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;protocolVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clientCapabilities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;readTextFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;writeTextFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;terminal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;clientInfo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-bot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Step 3: Create session&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;session/new&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/path/to/workspace&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;mcpServers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;clientCapabilities&lt;/code&gt; declaration is the key insight — it tells Kiro what your client can handle. Declare &lt;code&gt;fs.readTextFile: true&lt;/code&gt; and Kiro will send file read requests to your client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Kiro sends requests TO us when it needs tools&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleServerRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs/readTextFile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;terminal/execute&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;execSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Streaming Responses
&lt;/h3&gt;

&lt;p&gt;ACP streams responses via &lt;code&gt;session/update&lt;/code&gt; notifications — each containing a text chunk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="nx"&gt;acp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notification&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;sessionUpdate&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;agent_message_chunk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;session/prompt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sessionId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding MCP Tools
&lt;/h3&gt;

&lt;p&gt;MCP servers extend the agent with external capabilities. One JSON config gives the bot web search:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my-agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tools"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"web-search"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"duckduckgo-mcp-server"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask the bot "What's the weather in Tokyo?" — Kiro automatically invokes the search tool, processes results, and responds. All within a single &lt;code&gt;session/prompt&lt;/code&gt; call.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wiring Telegram
&lt;/h3&gt;

&lt;p&gt;The adapter is the simplest layer — receive, forward, respond:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;allowedUsers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendChatAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;typing&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;acp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;part&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nf"&gt;splitMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;part&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;~200 lines of code.&lt;/strong&gt; A fully functional mobile AI assistant that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Connects to Kiro CLI via ACP (JSON-RPC 2.0 over stdio)&lt;/li&gt;
&lt;li&gt;✅ Full workspace access — reads files, writes files, runs terminal commands&lt;/li&gt;
&lt;li&gt;✅ MCP tool integration — web search, AWS docs, custom tools&lt;/li&gt;
&lt;li&gt;✅ Streamed responses — no waiting for the full response to generate&lt;/li&gt;
&lt;li&gt;✅ Auth, typing indicators, automatic message splitting for Telegram's 4096 char limit&lt;/li&gt;
&lt;li&gt;✅ Channel-agnostic — adding Slack or Discord means writing one new adapter file&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Patterns That Made It Work
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Why It Matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Adapter Pattern&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Telegram adapter is decoupled from ACP. New channels = new adapter, same core.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;JSON-RPC 2.0 / stdio&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Same transport as LSP. Battle-tested, no HTTP overhead, works with any language.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Capability Negotiation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Client declares what it supports during &lt;code&gt;initialize&lt;/code&gt;. Forward-compatible.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bidirectional Requests&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Client sends prompts, agent sends tool requests back. Both sides are client and server.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Streaming via Notifications&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent streams chunks as generated. No polling, no buffering.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Key Learnings
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ACP is underutilized.&lt;/strong&gt; Most people use Kiro in the terminal or IDE. But ACP is a general-purpose protocol — any client that speaks JSON-RPC can connect.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MCP servers are the real power.&lt;/strong&gt; The bot isn't just a chatbot — it's an agent with tools. Web search, AWS docs, file operations. MCP turns text generation into action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;stdio is elegant.&lt;/strong&gt; No HTTP servers, no WebSocket complexity, no ports. Spawn a process, pipe JSON, done.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Adapter Pattern pays off immediately.&lt;/strong&gt; Started with Telegram. Slack would take an afternoon because the ACP client is completely separate.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;strong&gt;Multi-channel&lt;/strong&gt; — Slack and WhatsApp adapters using the same ACP client&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Voice messages&lt;/strong&gt; — Speech-to-text → prompt → response → voice note&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Serverless&lt;/strong&gt; — Lambda + API Gateway with Telegram webhooks&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Session persistence&lt;/strong&gt; — Resume conversations across restarts&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;The full source is open: &lt;strong&gt;&lt;a href="https://github.com/ajitnk-lab/kiro-acp-telegram-bot" rel="noopener noreferrer"&gt;kiro-acp-telegram-bot&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MIT-0 licensed. Fork it, extend it, build your own channels.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/ajitnk-lab/kiro-acp-telegram-bot.git
&lt;span class="nb"&gt;cd &lt;/span&gt;kiro-acp-telegram-bot
npm &lt;span class="nb"&gt;install
cp&lt;/span&gt; .env.example .env  &lt;span class="c"&gt;# add your Telegram token&lt;/span&gt;
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;I'd love your feedback:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What channels would you connect next?&lt;/li&gt;
&lt;li&gt;Would a serverless (Lambda) deployment be useful?&lt;/li&gt;
&lt;li&gt;What MCP servers would you want on your phone?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop a comment or open an issue on the repo. If you build something with this — a Slack bot, a Discord integration, a voice assistant — let me know. 🚀&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with &lt;a href="https://kiro.dev/cli/" rel="noopener noreferrer"&gt;Kiro CLI&lt;/a&gt; · &lt;a href="https://agentclientprotocol.com" rel="noopener noreferrer"&gt;Agent Client Protocol&lt;/a&gt; · &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;MCP&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://kiro.dev/docs/cli/" rel="noopener noreferrer"&gt;Kiro CLI Documentation&lt;/a&gt; — Installation, authentication, usage&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kiro.dev/docs/cli/acp/" rel="noopener noreferrer"&gt;Kiro ACP Integration Guide&lt;/a&gt; — Supported methods, session updates, Kiro extensions&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://agentclientprotocol.com" rel="noopener noreferrer"&gt;Agent Client Protocol Specification&lt;/a&gt; — The open standard for AI agent-editor communication&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kiro.dev/docs/cli/mcp/" rel="noopener noreferrer"&gt;Kiro MCP Configuration&lt;/a&gt; — Setting up MCP servers (stdio + HTTP)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kiro.dev/docs/cli/custom-agents/" rel="noopener noreferrer"&gt;Kiro Custom Agents&lt;/a&gt; — Agent JSON config, hooks, MCP server selection&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://modelcontextprotocol.io/introduction" rel="noopener noreferrer"&gt;Model Context Protocol&lt;/a&gt; — Anthropic's open standard for AI tool integration&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jsonrpc.org/specification" rel="noopener noreferrer"&gt;JSON-RPC 2.0 Specification&lt;/a&gt; — The transport protocol ACP is built on&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://core.telegram.org/bots/api" rel="noopener noreferrer"&gt;Telegram Bot API&lt;/a&gt; — Bot creation, message handling, polling vs webhooks&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kiro.dev/changelog/cli/1-25/" rel="noopener noreferrer"&gt;ACP Changelog — Kiro 1.25&lt;/a&gt; — ACP launch, MCP tools, session management&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/blogs/devops/exploring-the-latest-features-of-the-amazon-q-developer-cli/" rel="noopener noreferrer"&gt;Exploring the latest features of Amazon Q Developer CLI&lt;/a&gt; — Background on CLI + MCP architecture&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>aws</category>
      <category>devtools</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
