<?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: Kozo-KI</title>
    <description>The latest articles on DEV Community by Kozo-KI (@kozo-ki).</description>
    <link>https://dev.to/kozo-ki</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%2F3906970%2F807b14ec-dfb5-462e-be87-3109c23c14d1.png</url>
      <title>DEV Community: Kozo-KI</title>
      <link>https://dev.to/kozo-ki</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kozo-ki"/>
    <language>en</language>
    <item>
      <title>Building a Technical Literature Dashboard with Power Automate Power Apps LDX hub StructFlow</title>
      <dc:creator>Kozo-KI</dc:creator>
      <pubDate>Mon, 18 May 2026 23:51:51 +0000</pubDate>
      <link>https://dev.to/kozo-ki/building-a-technical-literature-dashboard-with-power-automate-power-apps-ldx-hub-structflow-3aa4</link>
      <guid>https://dev.to/kozo-ki/building-a-technical-literature-dashboard-with-power-automate-power-apps-ldx-hub-structflow-3aa4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Verification Case Report #006 — 2026.05.18 | Time spent: ~3 days&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Documents processed&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Power Apps screens&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Power Automate flows&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StructFlow extracted fields&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We built &lt;strong&gt;TechLit Viewer&lt;/strong&gt; — an end-to-end technical literature management system that uses LDX hub StructFlow to extract structured data from documents, Power Automate to keep everything updated, and both Power Apps and a standalone HTML dashboard for visualization.&lt;/p&gt;




&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Many customers express a need to continuously collect and evaluate technical literature across diverse fields. The old approach — storing PDFs and patent documents in folders — made it nearly impossible to answer questions like "which technologies are at which maturity level?" or "which documents are most relevant to our business?"&lt;/p&gt;

&lt;p&gt;We set out to verify whether a practical technical literature management system could be built within a no-code/low-code stack by combining LDX hub StructFlow for AI extraction with Microsoft 365 tools for storage, automation, and display.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What we're testing:&lt;/strong&gt; Can StructFlow turn unstructured technical documents (PDFs, patents, reports) into structured data that integrates cleanly with SharePoint, Power Automate, and Power Apps?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  System Architecture: 5 Layers
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// TechLit Viewer — System Overview

[1] INPUT         Source files (PDF / patents / reports)
                  └─ Stored in SharePoint document library. 18 documents total.

[2] AI EXTRACTION LDX hub StructFlow
                  └─ Auto-extracts 8 fields:
                     Title / DocType / Authors / Year / FieldMajor /
                     TRL / RelevanceScore / Summary

[3] DATA LAYER    SharePoint Lists (TechLit_Master / TechLit_Metrics)
                  └─ Power Automate writes; Power Apps + HTML dashboard reads.

[4] AUTOMATION    Power Automate (2 flows)
                  └─ ① Auto-extract on item update  (TechLit_Pipeline_UPDATE)
                     ② Manual bulk processing       (TechLit_BulkUpdate)

[5] DISPLAY       Power Apps (TechLit_Viewer) + HTML dashboard
                  └─ 4-screen Power Apps + standalone HTML dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Flow Design: Two Flows for Two Purposes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ① TechLit_Pipeline_UPDATE (always-on)
&lt;/h3&gt;

&lt;p&gt;Fires automatically when a SharePoint list item is updated. Detects new document registrations or changes to existing records, sends the file to StructFlow, and immediately writes the extracted results back. Day-to-day document additions are fully automated via this flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  ② TechLit_BulkUpdate (manual trigger)
&lt;/h3&gt;

&lt;p&gt;A manual-trigger flow for bulk processing all 18 documents. Used after schema changes, prompt revisions, or for initial data loading. Iterates through all items with a foreach loop, waits for StructFlow polling to complete, and writes results back to the list.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key design insight:&lt;/strong&gt; The update trigger excels at immediacy but isn't suited for full reprocessing. The manual trigger handles bulk operations well but requires operator action. Using both flows together covers both daily operations and administrative tasks.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  StructFlow Extraction Schema: 8 Fields
&lt;/h2&gt;

&lt;p&gt;Schema design started from the question: &lt;em&gt;"what do we want to decide?"&lt;/em&gt; — not &lt;em&gt;"what can we extract?"&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Title&lt;/td&gt;
&lt;td&gt;Document title&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DocType&lt;/td&gt;
&lt;td&gt;Document type (patent / paper / report / other)&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authors&lt;/td&gt;
&lt;td&gt;Authors / applicants&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Year&lt;/td&gt;
&lt;td&gt;Publication / filing year&lt;/td&gt;
&lt;td&gt;integer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FieldMajor&lt;/td&gt;
&lt;td&gt;Primary technology domain (Materials Science, Energy Engineering, etc.)&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TRL&lt;/td&gt;
&lt;td&gt;Technology Readiness Level (1–9)&lt;/td&gt;
&lt;td&gt;integer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RelevanceScore&lt;/td&gt;
&lt;td&gt;Relevance to our business (high / medium / low)&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Summary&lt;/td&gt;
&lt;td&gt;2–3 sentence technical summary&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;About TRL (Technology Readiness Level):&lt;/strong&gt; Originally developed by NASA and adopted by EU Horizon programs. Levels 1–3 = basic research, 4–6 = demonstration, 7–9 = operational/production. Quantifying maturity makes it easy to distinguish research-stage from production-ready technologies at a glance.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Power Apps: 4 Screens for Different Use Cases
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Screen&lt;/th&gt;
&lt;th&gt;Features&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Screen 1: Search&lt;/td&gt;
&lt;td&gt;Free-text search by title, author, or domain. Filtering by DocType, TRL, RelevanceScore. Real-time queries against SharePoint list.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Screen 2: Detail View&lt;/td&gt;
&lt;td&gt;Full field display for individual documents. Review StructFlow-extracted Summary. Visual TRL and relevance indicators.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Screen 3: Metrics Comparison&lt;/td&gt;
&lt;td&gt;TRL distribution by technology domain. Document count by relevance. Year-over-year trend charts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Screen 4: Tech Dashboard&lt;/td&gt;
&lt;td&gt;Advanced visualization via embedded HTML component. Dynamic charts with Chart.js. Integrated full-text search over all 18 documents.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  HTML Dashboard: Standalone Strategic View
&lt;/h2&gt;

&lt;p&gt;Alongside Power Apps, we built a standalone HTML dashboard (&lt;code&gt;techlit_dashboard.html&lt;/code&gt;) that runs entirely in the browser — no Power Apps dependency. This makes it easy to share with executives or external stakeholders.&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;// StructFlow extraction results stored directly as a data array&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Immobilized Photocatalyst Paper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;docType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;patent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[Author name masked]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2002&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;fieldMajor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Chemistry&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;trl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;relevance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;high&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;  &lt;span class="c1"&gt;// SourceFileUrl — will become a live link once populated&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&gt;// ... 18 documents total&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dashboard includes 4 charts (technology domain distribution, TRL distribution, year-over-year trend, document type breakdown) plus a searchable full-document table. Passing StructFlow's structured data to Chart.js generates all analysis charts automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  StructFlow Extraction Accuracy
&lt;/h3&gt;

&lt;p&gt;15 of 18 documents (83%) had all fields extracted correctly. The remaining 3 showed mixed-language inconsistencies in &lt;code&gt;FieldMajor&lt;/code&gt; (English vs. Japanese) — no impact on usability, but a clear prompt improvement opportunity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Power Automate Automation
&lt;/h3&gt;

&lt;p&gt;Average processing time per document: ~67 seconds (including StructFlow polling). Full run of all 18 documents: ~20 minutes. Both scheduled and trigger-based execution confirmed stable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technology Domain Visibility
&lt;/h3&gt;

&lt;p&gt;Environmental Science was the largest category (6 documents), followed by Materials Science (4). TRL distribution: basic research (1–3) was highest at 8 documents; operational stage (7–9) had 3. For the first time, we had a quantitative picture of the entire portfolio.&lt;/p&gt;

&lt;h3&gt;
  
  
  Relevance Scoring
&lt;/h3&gt;

&lt;p&gt;15 of 18 documents scored &lt;code&gt;RelevanceScore = High&lt;/code&gt;. By embedding our business context (translation &amp;amp; localization) into the StructFlow system prompt, we achieved automatic screening aligned with our actual evaluation criteria.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Biggest insight: from "searching" to "discovering"&lt;/strong&gt;&lt;br&gt;
Technical documents that could previously only be searched by filename can now be filtered across TRL, technology domain, and relevance simultaneously. Being able to instantly narrow down to "TRL ≥ 4 AND Materials Science AND High relevance" fundamentally changes the speed of technology strategy decisions.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Lock down SharePoint column types before you start
&lt;/h3&gt;

&lt;p&gt;Column types (hyperlink vs. single line of text) can't be changed after the fact. Confirm the format Power Automate will write, then finalize column design before building.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Design the StructFlow schema from your decision criteria
&lt;/h3&gt;

&lt;p&gt;Don't start from "what can we extract?" — start from "what do we need to decide?" Including evaluation-axis fields like &lt;code&gt;TRL&lt;/code&gt; and &lt;code&gt;RelevanceScore&lt;/code&gt; from the beginning dramatically increases dashboard value.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Separate Power Apps and HTML dashboard by purpose
&lt;/h3&gt;

&lt;p&gt;Power Apps suits day-to-day search and update operations; the HTML dashboard suits sharing and presentations. Using two UIs on the same data source expands both the audience and the use cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Control FieldMajor normalization via the prompt
&lt;/h3&gt;

&lt;p&gt;Mixed English/Japanese values like "Materials Science" and "材料科学" split aggregations. Adding an explicit instruction to the StructFlow system prompt ("always output technology domains in English") prevents this drift.&lt;/p&gt;




&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Populate SourceFileUrl&lt;/td&gt;
&lt;td&gt;Add source URLs to the SharePoint list so users can reach original documents in one click from the dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Schedule automation&lt;/td&gt;
&lt;td&gt;Move from manual triggers to fully automated monthly runs with auto-distribution to leadership&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Normalize FieldMajor&lt;/td&gt;
&lt;td&gt;Add English-only instruction to StructFlow prompt and reprocess all 18 documents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scale to 100+ documents&lt;/td&gt;
&lt;td&gt;Add ExtractDoc as a pre-processing step to handle scanned PDFs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RefineLoop integration&lt;/td&gt;
&lt;td&gt;Auto-translate and improve summaries of foreign-language documents (English, Chinese) into Japanese&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;Kawamura International is a translation and localization company documenting its AI process experiments in public. StructFlow, RefineLoop, RenderOCR — and whatever comes next.&lt;/p&gt;

</description>
      <category>powerautomate</category>
      <category>powerapps</category>
      <category>ai</category>
      <category>structflow</category>
    </item>
    <item>
      <title>We fed meeting minutes to AI without structure — and lost 70% of the data we needed for decisions</title>
      <dc:creator>Kozo-KI</dc:creator>
      <pubDate>Wed, 13 May 2026 04:23:06 +0000</pubDate>
      <link>https://dev.to/kozo-ki/we-fed-meeting-minutes-to-ai-without-structure-and-lost-70-of-the-data-we-needed-for-decisions-4k49</link>
      <guid>https://dev.to/kozo-ki/we-fed-meeting-minutes-to-ai-without-structure-and-lost-70-of-the-data-we-needed-for-decisions-4k49</guid>
      <description>&lt;p&gt;I'm Kozo Moriguchi, CEO of Kawamura International.&lt;/p&gt;

&lt;p&gt;We started in translation and localization, moved into MT SaaS, and now I'm focused on building out the LDX business. I'm not an engineer — but I test and rebuild business processes with AI, and I write about what actually happens.&lt;/p&gt;

&lt;p&gt;This is Part 5 of that series. The question this time: &lt;strong&gt;can you build a reliable management dashboard by just handing your meeting minutes to an AI?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The context: most companies can only use Copilot
&lt;/h2&gt;

&lt;p&gt;When you try to bring AI into enterprise workflows, you hit a wall quickly.&lt;/p&gt;

&lt;p&gt;Many organizations — due to security policies or vendor agreements — restrict which AI tools employees can use. Claude, ChatGPT: blocked. Copilot: allowed. I've seen this pattern repeatedly across companies we work with.&lt;/p&gt;

&lt;p&gt;That's why I ran this test. If Copilot is all you have, what can it actually do? And how does it compare to using LDX hub StructFlow to extract structured data first?&lt;/p&gt;

&lt;p&gt;I used 20 departments worth of real meeting minutes and ran both approaches on the same data.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we tested
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Copilot approach&lt;/strong&gt;&lt;br&gt;
Paste meeting minutes into Microsoft Copilot. Ask it to organize the data into an HTML management dashboard. No schema defined. Let Copilot decide what's important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;StructFlow approach&lt;/strong&gt;&lt;br&gt;
Define a schema upfront (tasks, risks, cross-department requests as structured JSON). Run StructFlow via LDX hub API. Use Power Automate to generate an HTML dashboard with Chart.js charts. Save to SharePoint. Return the URL to Copilot Studio.&lt;/p&gt;

&lt;p&gt;Same input data. Same goal. Different method.&lt;/p&gt;


&lt;h2&gt;
  
  
  See the dashboards yourself
&lt;/h2&gt;

&lt;p&gt;Rather than just describing the difference, here are both dashboards built from the same 20-department dataset.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copilot-generated dashboard (sample)&lt;/strong&gt;&lt;br&gt;
👉 &lt;a href="https://kozo-ki.github.io/ldxhub-dashboard-demo/dashboard_copilot_20dept.html" rel="noopener noreferrer"&gt;Open dashboard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copilot + LDX hub StructFlow dashboard (sample)&lt;/strong&gt;&lt;br&gt;
👉 &lt;a href="https://kozo-ki.github.io/ldxhub-dashboard-demo/dashboard_structflow_20dept.html" rel="noopener noreferrer"&gt;Open dashboard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;These pages are unlisted (no-index) and contain no real company data. URL access only.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Looking at them side by side, the difference in information density becomes immediately visible — before you even look at the numbers below.&lt;/p&gt;


&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;StructFlow&lt;/th&gt;
&lt;th&gt;Copilot&lt;/th&gt;
&lt;th&gt;Difference&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tasks extracted&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-82&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Risks extracted&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;45&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~16&lt;/td&gt;
&lt;td&gt;Significantly fewer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-dept requests&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;83&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~17&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-66&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-severity risks&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;21&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-15&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Departments processed&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;20/20&lt;/td&gt;
&lt;td&gt;Same&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;From the same 20 departments of meeting notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;5.5× more tasks&lt;/strong&gt; extracted with StructFlow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2.6× more risks&lt;/strong&gt; surfaced&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4.9× more cross-department dependencies&lt;/strong&gt; identified&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Copilot didn't fail to read the documents. It read them, summarized them, and produced a polished HTML output. But in the process of summarizing, &lt;strong&gt;an enormous amount of information was compressed away&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  What specifically got dropped
&lt;/h2&gt;

&lt;p&gt;The quantitative gap is significant. But what matters more is &lt;em&gt;what&lt;/em&gt; fell through.&lt;/p&gt;

&lt;p&gt;Here's what Copilot's dashboard was missing that StructFlow caught:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;① Operations team overload — 3 simultaneous cases, high attrition risk&lt;/strong&gt;&lt;br&gt;
StructFlow: extracted as 3 separate structured task items with named assignees and risk flags.&lt;br&gt;
Copilot: compressed to "resource reallocation needed."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;② Finance team: M&amp;amp;A accounting and audit response&lt;/strong&gt;&lt;br&gt;
StructFlow: specific tasks with deadlines.&lt;br&gt;
Copilot: not mentioned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;③ Partner team: top 3 partners = 70% of revenue (concentration risk)&lt;/strong&gt;&lt;br&gt;
A significant business continuity risk.&lt;br&gt;
Copilot: not mentioned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;④ QA team: 2 security vulnerabilities&lt;/strong&gt;&lt;br&gt;
StructFlow: extracted as independent risk items.&lt;br&gt;
Copilot: buried in another department's section.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⑤ Facilities: monthly office rent at ¥32M&lt;/strong&gt;&lt;br&gt;
A concrete cost figure.&lt;br&gt;
Copilot: omitted entirely.&lt;/p&gt;

&lt;p&gt;The dangerous part isn't that these were summarized — it's that &lt;strong&gt;you wouldn't know they were missing&lt;/strong&gt;. Looking at a clean Copilot-generated dashboard, there's no indication that any of this exists. The gap only became visible when we had the StructFlow version to compare against.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why "just ask the AI" fails structurally
&lt;/h2&gt;

&lt;p&gt;There are four structural reasons why unstructured AI extraction breaks down for management reporting:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Summarization pressure&lt;/strong&gt;&lt;br&gt;
LLMs are optimized to produce readable output. Given a long document, they compress it using their own judgment about what matters. That judgment is based on training data — not your company's priorities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. No consistent format = no trend analysis&lt;/strong&gt;&lt;br&gt;
Copilot's output format changes every run. If last month's dashboard has different columns than this month's, you can't track trends. A management dashboard needs consistent structure by definition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. You can't see what's missing&lt;/strong&gt;&lt;br&gt;
This is the most dangerous failure mode. A well-formatted summary looks complete. You only discover the gaps when you have a structured comparison. In practice, most teams would never run both approaches side by side — so the gaps stay invisible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Doesn't scale&lt;/strong&gt;&lt;br&gt;
StructFlow processes 20 departments at the same cost as 5. Ask Copilot to handle 30 departments in one prompt and output quality degrades. The approaches scale in opposite directions.&lt;/p&gt;


&lt;h2&gt;
  
  
  Where Copilot genuinely wins
&lt;/h2&gt;

&lt;p&gt;To be fair: Copilot has real strengths.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;KPI snapshots&lt;/strong&gt; — organizing revenue, churn rate, and utilization into a summary view is something Copilot does quickly and well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design quality&lt;/strong&gt; — the HTML output looks polished. Good for executive presentations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Narrative context&lt;/strong&gt; — Copilot understands "A company deal → technical proposal → executive meeting" as a sequence. It writes it as a coherent story.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The honest summary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For "quickly get a sense of things before a meeting" → Copilot&lt;/li&gt;
&lt;li&gt;For "make sure nothing critical is missed" → StructFlow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't competing tools. They serve different purposes.&lt;/p&gt;


&lt;h2&gt;
  
  
  The pipeline that's running now
&lt;/h2&gt;

&lt;p&gt;Here's the StructFlow setup we built:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Meeting minutes (SharePoint files)
    ↓
Power Automate (batch processing flow)
    ↓
LDX hub StructFlow API (JSON structured output)
    ↓ polling every 3 seconds (Do Until)
HTML dashboard generation (with Chart.js)
    ↓
Saved to SharePoint → URL returned to Copilot Studio
    ↓
User views in browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key piece: Power Automate's "Create file" action writes the full HTML (including &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags) to SharePoint as a static file. Chart.js runs fine in that context. Copilot Studio returns the URL to the user.&lt;/p&gt;

&lt;p&gt;Total setup time from zero: about 3 hours, including all the wrong turns.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next: multilingual dashboards
&lt;/h2&gt;

&lt;p&gt;LDX hub has another API alongside StructFlow: &lt;strong&gt;RefineLoop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;RefineLoop is designed for translation quality refinement. But combined with StructFlow, it opens up an interesting use case: companies with global operations often have meeting notes in multiple languages — English, Japanese, Spanish, Mandarin. StructFlow extracts structured data from each. RefineLoop normalizes and quality-checks the translation into a unified language. The result: a single dashboard aggregating data from every regional office, regardless of what language their notes were written in.&lt;/p&gt;

&lt;p&gt;Given that Kawamura International's roots are in translation and localization, this is a direction we're particularly interested in building out.&lt;/p&gt;




&lt;h2&gt;
  
  
  Coming up: n8n and Dify
&lt;/h2&gt;

&lt;p&gt;I will run the same test on &lt;strong&gt;n8n&lt;/strong&gt; and &lt;strong&gt;Dify&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Power Automate is a Microsoft-native tool. n8n is an open-source workflow automation platform you can self-host. Dify is an LLM app development framework. Same StructFlow API underneath — but the surrounding infrastructure changes. I want to know what that changes in practice.&lt;/p&gt;

&lt;p&gt;If you're locked into a Microsoft environment, the setup from this post should work for you. If you have more flexibility, stay tuned for Part 6.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Kawamura International is actively testing AI integration across translation and localization workflows. We publish findings through LDX Lab as we go.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>powerautomate</category>
      <category>ldxhub</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>I batch-processed 20 meeting minutes with Power Automate + LDX hub. It took 2 days and 8 HTTP actions.</title>
      <dc:creator>Kozo-KI</dc:creator>
      <pubDate>Tue, 12 May 2026 00:19:44 +0000</pubDate>
      <link>https://dev.to/kozo-ki/i-batch-processed-20-meeting-minutes-with-power-automate-ldx-hub-it-took-2-days-and-8-http-4ch5</link>
      <guid>https://dev.to/kozo-ki/i-batch-processed-20-meeting-minutes-with-power-automate-ldx-hub-it-took-2-days-and-8-http-4ch5</guid>
      <description>&lt;p&gt;&lt;em&gt;This is Part 4 of a series documenting a non-engineer CEO's attempts to connect Copilot Studio and Power Automate to LDX hub's StructFlow API.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;a href="https://dev.to/kozo-ki/a-non-engineer-ceo-tried-to-connect-copilot-studio-to-ldx-hub-heres-what-happened-356k"&gt;Part 1&lt;/a&gt; — It didn't work yet. &lt;a href="https://dev.to/kozo-ki/a-non-engineer-ceo-connected-copilot-studio-to-ldx-hub-it-took-8-errors-and-3-hours-heres-the-5cdh"&gt;Part 2&lt;/a&gt; — REST API via Power Automate, finally working. &lt;a href="https://dev.to/kozo-ki/part-3-i-skipped-power-automate-and-connected-ldx-hub-directly-via-mcp-it-worked-in-2-hours-gdg"&gt;Part 3&lt;/a&gt; — MCP direct connection, 2 hours.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In Part 3, I connected LDX hub directly to Copilot Studio via MCP. One record at a time, in a chat interface. It worked great.&lt;/p&gt;

&lt;p&gt;But then I asked the obvious question: what about 20 files? Batch processing 20 Word documents from SharePoint, extracting structured data from each, and synthesizing them into a single company-wide dashboard?&lt;/p&gt;

&lt;p&gt;That's not a job for MCP. That's a job for Power Automate.&lt;/p&gt;

&lt;p&gt;This is the story of building that pipeline — every error, every detour, and the moment it finally worked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I built:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microsoft Power Automate flow&lt;/li&gt;
&lt;li&gt;20 Word files in SharePoint&lt;/li&gt;
&lt;li&gt;LDX hub ExtractDoc + StructFlow (REST API, not MCP)&lt;/li&gt;
&lt;li&gt;Output: HTML management dashboard saved to SharePoint&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Time required: ~2 days&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SharePoint (20 Word files)
  ↓ Get files (properties only)
  ↓ Initialize array variable: results[]
  ↓ Apply to each file:
    ├─ Get file content (by path)
    ├─ POST /uploads → file_id (upload session)
    ├─ PUT /uploads/{file_id} → upload binary (base64)
    ├─ POST /extractdoc/jobs → job_id
    ├─ Do until status = completed (poll GET /extractdoc/jobs/{job_id})
    ├─ GET /files/{output_file_id}/content → extracted text
    ├─ POST /structflow/jobs → job_id
    └─ Do until status = completed (poll GET /structflow/jobs/{job_id})
        → append body to results[]
  ↓ POST /structflow/jobs (cross-dept analysis)
  ↓ Do until status = completed
  ↓ Compose HTML dashboard
  ↓ Create file in SharePoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;8 HTTP actions per file. 20 files. Sequential processing.&lt;/p&gt;


&lt;h2&gt;
  
  
  The errors, in order
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Error 1: Wrong upload endpoint
&lt;/h3&gt;

&lt;p&gt;I started with &lt;code&gt;POST /api/v1/uploads&lt;/code&gt;. Got 404.&lt;/p&gt;

&lt;p&gt;The correct endpoint (without the &lt;code&gt;/api/v1&lt;/code&gt; prefix) is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST https://gw.ldxhub.io/uploads
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lesson: check the API docs directly. The base URL doesn't always include a version prefix.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 2: File content — multipart/form-data nightmare
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;POST /files&lt;/code&gt; requires &lt;code&gt;multipart/form-data&lt;/code&gt;. Power Automate's HTTP connector doesn't handle this cleanly.&lt;/p&gt;

&lt;p&gt;The workaround: use the &lt;strong&gt;chunk upload flow&lt;/strong&gt; instead.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;POST /uploads&lt;/code&gt; — creates an upload session, returns &lt;code&gt;file_id&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PUT /uploads/{file_id}&lt;/code&gt; — sends the file content as base64 JSON
&lt;/li&gt;
&lt;/ol&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;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@{base64(body('パスによるファイル_コンテンツの取得'))}"&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;This is the JSON-based chunk upload designed for MCP clients, but it works perfectly from Power Automate too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 3: File not found (SharePoint path)
&lt;/h3&gt;

&lt;p&gt;Getting file content by ID didn't work. The fix: use &lt;strong&gt;"Get file content by path"&lt;/strong&gt; instead of "Get file content".&lt;/p&gt;

&lt;p&gt;The correct path format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;concat('/Shared Documents/General/LDXhubtest/', items('それぞれに適用する')?['{FilenameWithExtension}'])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The field name is &lt;code&gt;{FilenameWithExtension}&lt;/code&gt; (with curly braces) — found by inspecting the raw output of the "Get files" action.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 4: ExtractDoc engine name
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;"engine": "docx"&lt;/code&gt; returned an error. The correct engine ID:&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;"engine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ki/extract"&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;Check available engines with &lt;code&gt;GET /extractdoc/engines&lt;/code&gt; first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 5: Do until condition syntax
&lt;/h3&gt;

&lt;p&gt;Power Automate's new designer is strict about condition expressions. This fails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@{body('HTTP_3')?['status']}  equals  completed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works (in advanced mode):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@equals(body('HTTP_3')?['status'],'completed')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error 6: ExtractDoc doesn't return text directly
&lt;/h3&gt;

&lt;p&gt;I assumed ExtractDoc would return the extracted text in the response body. It doesn't.&lt;/p&gt;

&lt;p&gt;The response contains &lt;code&gt;output_file_id&lt;/code&gt;. You then need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /files/{output_file_id}/content
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to download the actual text. This requires an extra HTTP action between ExtractDoc polling and StructFlow job creation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 7: Array variable append — null value
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;AppendToArrayVariable&lt;/code&gt; with &lt;code&gt;body('HTTP_5')?['results']&lt;/code&gt; returned a null error.&lt;/p&gt;

&lt;p&gt;Fix: append &lt;code&gt;body('HTTP_5')&lt;/code&gt; (the entire response), not just the results field.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error 8: Cross-scope reference error
&lt;/h3&gt;

&lt;p&gt;When I tried to reference loop-scoped actions from outside the loop (for the cross-department analysis step), Power Automate threw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The action 'HTTP_5' is nested in a foreach scope of multiple levels. 
Referencing repetition actions from outside the scope is not supported.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The solution: accumulate everything into the &lt;code&gt;results&lt;/code&gt; array variable &lt;em&gt;inside&lt;/em&gt; the loop, then pass &lt;code&gt;variables('results')&lt;/code&gt; to the final analysis step outside the loop.&lt;/p&gt;




&lt;h2&gt;
  
  
  The working flow — key settings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  File upload (HTTP)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;URI:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://gw.ldxhub.io/uploads&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Method:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Headers:&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;Content-Type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;application/json&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;Authorization:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Bearer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Body:&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;"filename"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@{items('それぞれに適用する')?['{FilenameWithExtension}']}"&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;h3&gt;
  
  
  File content upload (HTTP 1)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;URI:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://gw.ldxhub.io/uploads/@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;body('HTTP')?&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'file_id'&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Method:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;PUT&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Body:&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;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@{base64(body('パスによるファイル_コンテンツの取得'))}"&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;h3&gt;
  
  
  ExtractDoc job (HTTP 2)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;URI:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;https://gw.ldxhub.io/extractdoc/jobs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Method:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Body:&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;"engine"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ki/extract"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"file_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@{body('HTTP')?['file_id']}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"output_format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&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;h3&gt;
  
  
  Download extracted text (HTTP 8, after polling)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;URI: https://gw.ldxhub.io/files/@{body('HTTP_3')?['output_file_id']}/content
Method: GET
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  StructFlow job (HTTP 4)
&lt;/h3&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;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"anthropic/claude-sonnet-4-6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"system_prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&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;"example_output"&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="err"&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;"inputs"&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="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"data"&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="nl"&gt;"minutes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@{body('HTTP_8')}"&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;h2&gt;
  
  
  The result
&lt;/h2&gt;

&lt;p&gt;After 2 days of iteration:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Departments processed&lt;/td&gt;
&lt;td&gt;20 / 20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;StructFlow jobs completed&lt;/td&gt;
&lt;td&gt;20 / 20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total tasks extracted&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High-severity risks identified&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-department dependency entries&lt;/td&gt;
&lt;td&gt;60+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The HTML dashboard shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Company-wide task list (all 100, with assignee, deadline, related dept)&lt;/li&gt;
&lt;li&gt;Risk cards by severity (color-coded)&lt;/li&gt;
&lt;li&gt;Cross-department dependency map&lt;/li&gt;
&lt;li&gt;Per-department summary cards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key insight on architecture:&lt;/strong&gt; LDX hub handles all the intelligence — text extraction (ExtractDoc) and structured data generation (StructFlow). The HTML template I wrote just renders the JSON. The processing engine and presentation layer are fully separated.&lt;/p&gt;




&lt;h2&gt;
  
  
  MCP vs REST API — the actual comparison
&lt;/h2&gt;

&lt;p&gt;Now that I've done both, here's the honest breakdown:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;MCP (Part 3)&lt;/th&gt;
&lt;th&gt;REST API — Power Automate (Part 4)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Setup time&lt;/td&gt;
&lt;td&gt;~2 hours&lt;/td&gt;
&lt;td&gt;~2 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Errors&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;8+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Single record, interactive&lt;/td&gt;
&lt;td&gt;Batch processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20-file batch&lt;/td&gt;
&lt;td&gt;❌ Not practical&lt;/td&gt;
&lt;td&gt;✅ Right tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Polling complexity&lt;/td&gt;
&lt;td&gt;Handled by agent&lt;/td&gt;
&lt;td&gt;Manual Do until loops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File upload&lt;/td&gt;
&lt;td&gt;Via MCP chunk API&lt;/td&gt;
&lt;td&gt;Via REST chunk upload&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;MCP wins on simplicity for conversational use cases. REST API wins for scheduled batch jobs.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'd do differently
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Test with 1 file before 20.&lt;/strong&gt; I wasted hours debugging a flow that was running on all 20 files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check the API docs before assuming endpoint paths.&lt;/strong&gt; The &lt;code&gt;/api/v1/&lt;/code&gt; prefix doesn't exist on all endpoints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify Do until conditions in advanced mode.&lt;/strong&gt; The GUI condition builder generates subtly wrong expressions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add error handling.&lt;/strong&gt; The current flow times out silently if an API call fails mid-loop.&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;Phase 2: A quality comparison between two approaches to dashboard generation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structured data route&lt;/strong&gt;: StructFlow extracts JSON → HTML renders JSON (what we built)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unstructured data route&lt;/strong&gt;: raw meeting text passed directly to an LLM → HTML rendered from prose output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hypothesis: structured data produces more consistent, queryable, and accurate dashboards. But how much better, exactly? And at what cost difference? That's the next experiment.&lt;/p&gt;




&lt;p&gt;Kawamura International is a translation and localization company documenting its AI process experiments in public. StructFlow, RefineLoop, RenderOCR — and whatever comes next.&lt;/p&gt;

</description>
      <category>powerautomate</category>
      <category>ldxhub</category>
      <category>ai</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>I skipped Power Automate and connected LDX hub directly via MCP. It worked in 2 hours.</title>
      <dc:creator>Kozo-KI</dc:creator>
      <pubDate>Sun, 10 May 2026 23:21:01 +0000</pubDate>
      <link>https://dev.to/kozo-ki/part-3-i-skipped-power-automate-and-connected-ldx-hub-directly-via-mcp-it-worked-in-2-hours-gdg</link>
      <guid>https://dev.to/kozo-ki/part-3-i-skipped-power-automate-and-connected-ldx-hub-directly-via-mcp-it-worked-in-2-hours-gdg</guid>
      <description>&lt;p&gt;&lt;em&gt;This is Part 3 of a series documenting a non-engineer CEO's attempts to connect Copilot Studio to LDX hub's StructFlow API.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;a href="https://dev.to/kozo-ki/a-non-engineer-ceo-tried-to-connect-copilot-studio-to-ldx-hub-heres-what-happened-356k"&gt;Part 1&lt;/a&gt; — It didn't work yet. &lt;a href="https://dev.to/kozo-ki/a-non-engineer-ceo-connected-copilot-studio-to-ldx-hub-it-took-8-errors-and-3-hours-heres-the-5cdh"&gt;Part 2&lt;/a&gt; — REST API, 8 errors, 3 hours, finally working.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In Part 2, I got the REST API route working through Power Automate. It took 3 hours and 8 errors. The moment it worked, I immediately wondered: is there a simpler path?&lt;/p&gt;

&lt;p&gt;There is. It's called MCP.&lt;/p&gt;

&lt;p&gt;Instead of building a Power Automate flow, configuring polling loops, and debugging HTTP connectors — I connected LDX hub's MCP server directly to the Copilot Studio agent. The whole thing took about 2 hours, and most of that was figuring out two non-obvious settings.&lt;/p&gt;

&lt;p&gt;Here's the full account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microsoft Copilot Studio (Kawamura International tenant)&lt;/li&gt;
&lt;li&gt;LDX hub MCP Server (&lt;code&gt;https://gw.ldxhub.io/mcp&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Existing agent: Minutes Assistant (議事録アシスタント)&lt;/li&gt;
&lt;li&gt;Time required: ~2 hours&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Why MCP instead of Power Automate?
&lt;/h2&gt;

&lt;p&gt;The REST API route in Part 2 works. But it required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building a Do Until polling loop&lt;/li&gt;
&lt;li&gt;Debugging HTTP connector confusion (white vs green)&lt;/li&gt;
&lt;li&gt;Dealing with triggerBody() reference errors&lt;/li&gt;
&lt;li&gt;Managing variable types for async results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MCP eliminates all of that. The agent calls the tool directly — no middleware, no flow to maintain. If the tradeoff is acceptable for your use case, it's a significantly faster path to get running.&lt;/p&gt;

&lt;p&gt;The tradeoff: MCP is better suited for interactive, single-record use cases. For batch processing 20 files, Power Automate is still the right answer. More on that in Part 4.&lt;/p&gt;


&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;At Kawamura International, we're building generative AI-driven business processes across the company. This verification focused on integrating LDX hub's StructFlow (structured data extraction) into our "Minutes Assistant" Copilot Studio agent — automatically extracting the following from meeting transcripts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tasks &amp;amp; action items (with assignee and due date)&lt;/li&gt;
&lt;li&gt;Decisions made&lt;/li&gt;
&lt;li&gt;Per-speaker summaries&lt;/li&gt;
&lt;li&gt;Next meeting agenda candidates&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User (pastes meeting transcript)
  ↓
Copilot Studio "Minutes Assistant"
  ↓ MCP tools/call (Streamable HTTP)
LDX hub MCP Server (https://gw.ldxhub.io/mcp)
  ↓ createStructFlowJob
StructFlow Engine (async job)
  ↓ getStructFlowJob (polling)
Structured JSON result
  ↓
Copilot Studio formats and responds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 1: Verify the Endpoint Before Connecting
&lt;/h2&gt;

&lt;p&gt;Before touching Copilot Studio, verify that the LDX hub MCP endpoint meets the requirements.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Important: SSE transport is deprecated after August 2025&lt;/strong&gt;&lt;br&gt;
Copilot Studio dropped SSE support and now requires &lt;strong&gt;Streamable HTTP only&lt;/strong&gt;. Always verify the protocol before attempting a connection.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Run this in PowerShell to check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$headers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&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="s2"&gt;"Content-Type"&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Accept"&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"application/json, text/event-stream"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Authorization"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer YOUR_API_KEY"&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="nv"&gt;$body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nv"&gt;$r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Invoke-WebRequest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-UseBasicParsing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;-Uri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://gw.ldxhub.io/mcp"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;`
&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;-Method&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Headers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$headers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$body&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Status:"&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="nv"&gt;$r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StatusCode&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="c"&gt;# → 200&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Content-Type:"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# → application/json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Write-Host&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Body:"&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="nv"&gt;$r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Content&lt;/span&gt;&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="c"&gt;# → protocolVersion: 2025-03-26, 26 tools&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What to look for:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Expected&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTTP Status&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Endpoint reachable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content-Type&lt;/td&gt;
&lt;td&gt;&lt;code&gt;application/json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Streamable HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;protocolVersion&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2025-03-26&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Latest protocol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tools count&lt;/td&gt;
&lt;td&gt;26&lt;/td&gt;
&lt;td&gt;createStructFlowJob, getStructFlowJob, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you get HTTP 405 or 404, the server may only support the old SSE transport — which Copilot Studio no longer accepts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Add the MCP Server in Copilot Studio
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ① Enable Generative Orchestration first
&lt;/h3&gt;

&lt;p&gt;Agent settings → Generative AI → Select &lt;strong&gt;"Yes, use available tools and knowledge dynamically"&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Without this, MCP tools will never be called — no matter what you configure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  ② Add the MCP Tool
&lt;/h3&gt;

&lt;p&gt;Agent → Tools tab → &lt;strong&gt;Add a tool&lt;/strong&gt; → &lt;strong&gt;New MCP tool&lt;/strong&gt; → Fill in the wizard:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server URL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://gw.ldxhub.io/mcp&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication&lt;/td&gt;
&lt;td&gt;API Key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Key value&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Bearer {your_api_key}&lt;/code&gt; ← &lt;strong&gt;include the prefix&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Header name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Authorization&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  ③ Create the connection
&lt;/h3&gt;

&lt;p&gt;Click "Not connected" dropdown → "Create new connection" → Enter the API key → "Create".&lt;/p&gt;

&lt;p&gt;A green dot confirms a successful connection.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;The #1 gotcha: Bearer prefix&lt;/strong&gt;&lt;br&gt;
The API Key field in Copilot Studio sends the value as-is in the Authorization header. If you enter just the raw key without &lt;code&gt;Bearer&lt;/code&gt;, LDX hub returns a 403 error. Always enter &lt;code&gt;Bearer {key}&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 3: Add the System Prompt
&lt;/h2&gt;

&lt;p&gt;In the agent's overview tab, paste this into the &lt;strong&gt;Instructions&lt;/strong&gt; field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are an assistant that structures meeting minutes.

When the user provides meeting transcript text, always call the
createStructFlowJob tool from LDX hub MCP test to extract:

- Tasks and action items (with assignee and due date)
- Decisions made
- Per-speaker summaries
- Next meeting agenda candidates

After creating the job, poll using getStructFlowJob until status
is "completed", then format and display the results.

Respond in Japanese using tables and lists for readability.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: You don't need to manually specify &lt;code&gt;system_prompt&lt;/code&gt; or &lt;code&gt;example_output&lt;/code&gt; for StructFlow here — the agent's LLM generates those automatically at runtime.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;We fed in a real sales team monthly review transcript (5 participants, ~600 characters in Japanese). Here's what came back:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;th&gt;Quality&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tasks &amp;amp; action items&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;✅ Assignees and deadlines accurate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decisions&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;✅ All correct&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-speaker summaries&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;✅ Roles and contributions reflected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next agenda candidates&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;✅ Inferred implicit items too&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Confirmed MCP execution via activity log:&lt;/strong&gt;&lt;br&gt;
The activity log showed "LDX hub MCP — Working / Initialized" with &lt;code&gt;createStructFlowJob&lt;/code&gt; and &lt;code&gt;getStructFlowJob&lt;/code&gt; call records — confirming that StructFlow was actually invoked via MCP, not just processed by Copilot Studio's internal LLM.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Verify SSE vs Streamable HTTP before connecting&lt;/strong&gt;&lt;br&gt;
Copilot Studio dropped SSE after August 2025. Send an &lt;code&gt;initialize&lt;/code&gt; request first and confirm &lt;code&gt;protocolVersion: 2025-03-26&lt;/code&gt; in the response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. API Key needs the &lt;code&gt;Bearer&lt;/code&gt; prefix&lt;/strong&gt;&lt;br&gt;
The API Key field passes its value directly as the Authorization header value. Omitting &lt;code&gt;Bearer&lt;/code&gt; causes a 403 on the LDX hub side.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Generative Orchestration must be on&lt;/strong&gt;&lt;br&gt;
Check this before anything else. It's the gate that controls whether MCP tools get called at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Verify actual MCP calls via the activity log&lt;/strong&gt;&lt;br&gt;
You can confirm whether the agent truly called an MCP tool (vs. just using its internal LLM) by checking the activity log. Look for the tool name and "Working" status.&lt;/p&gt;




&lt;h2&gt;
  
  
  MCP vs REST API: Which should you use?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;MCP&lt;/th&gt;
&lt;th&gt;REST API (Power Automate)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Setup time&lt;/td&gt;
&lt;td&gt;~2 hours&lt;/td&gt;
&lt;td&gt;~3 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Errors encountered&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Middleware required&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Power Automate flow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Interactive, single-record&lt;/td&gt;
&lt;td&gt;Batch processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20-file batch processing&lt;/td&gt;
&lt;td&gt;❌ Not practical&lt;/td&gt;
&lt;td&gt;✅ Right tool&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a single record in a chat interface, MCP is the simpler path. For batch processing 20 meeting minutes files from SharePoint — that's Part 4.&lt;/p&gt;




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

&lt;p&gt;Part 4: Batch processing 20 meeting minutes files from SharePoint via Power Automate — building a cross-departmental management dashboard as the output.&lt;/p&gt;

&lt;p&gt;The MCP route works well for one record at a time. But when you need to process 20 Word files, extract structured data from each, and synthesize them into a single company-wide view, Power Automate is the right tool. That's what we're building next.&lt;/p&gt;




&lt;p&gt;Kawamura International is a translation and localization company documenting its AI process experiments in public. StructFlow, RefineLoop, RenderOCR — and whatever comes next.&lt;/p&gt;

</description>
      <category>githubcopilot</category>
      <category>mcp</category>
      <category>ai</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>A non-engineer CEO connected Copilot Studio to LDX hub. It took 8 errors and 3 hours. Here's the full log.</title>
      <dc:creator>Kozo-KI</dc:creator>
      <pubDate>Fri, 08 May 2026 01:20:04 +0000</pubDate>
      <link>https://dev.to/kozo-ki/a-non-engineer-ceo-connected-copilot-studio-to-ldx-hub-it-took-8-errors-and-3-hours-heres-the-5cdh</link>
      <guid>https://dev.to/kozo-ki/a-non-engineer-ceo-connected-copilot-studio-to-ldx-hub-it-took-8-errors-and-3-hours-heres-the-5cdh</guid>
      <description>&lt;p&gt;I'm the CEO of a translation company. Not an engineer.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://dev.to/"&gt;Part 1&lt;/a&gt;, I tried to connect Copilot Studio to LDX hub's &lt;a href="https://ldxlab.io/ldxhub/structflow" rel="noopener noreferrer"&gt;StructFlow&lt;/a&gt; API and hit a wall before getting anything to work. This is Part 2 — the completion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It works now.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I pasted meeting minutes into a Copilot Studio chat. It returned structured action items with assignees, tasks, and deadlines. It even interpreted "next week" as a specific date (May 8, Friday) based on the meeting date — and flagged it as an assumption for me to verify.&lt;/p&gt;

&lt;p&gt;Here's everything that happened between Part 1 and that result.&lt;/p&gt;




&lt;h2&gt;
  
  
  The root cause of BadGateway
&lt;/h2&gt;

&lt;p&gt;The HTTP action I'd been using — "Send an HTTP request" — was actually routed through the &lt;strong&gt;Office 365 Users connector&lt;/strong&gt;, not a raw HTTP connector. That's why every request to LDX hub returned BadGateway.&lt;/p&gt;

&lt;p&gt;The fix: use the green &lt;strong&gt;HTTP connector&lt;/strong&gt; under "Built-in tools" in Power Automate. It looks similar to the white Office connector but behaves completely differently. The green one makes actual HTTP calls to external APIs.&lt;/p&gt;

&lt;p&gt;This distinction isn't obvious from the UI. It cost me most of Part 1.&lt;/p&gt;




&lt;h2&gt;
  
  
  Switching to Agent Flows
&lt;/h2&gt;

&lt;p&gt;The Power Automate flow I built never appeared in Copilot Studio's tool list, despite being in the same environment. I never resolved why.&lt;/p&gt;

&lt;p&gt;The workaround: build the flow directly from Copilot Studio's left sidebar → "Flows" → "Agent flows." This creates a flow that's natively connected to the agent from the start.&lt;/p&gt;

&lt;p&gt;Same green HTTP connector, same logic — just a different entry point.&lt;/p&gt;




&lt;h2&gt;
  
  
  The error log (all 8 of them)
&lt;/h2&gt;

&lt;p&gt;I'm including every error in sequence. Each one moved me closer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;① BadGateway&lt;/strong&gt;&lt;br&gt;
Cause: Office 365 connector instead of HTTP connector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;② &lt;code&gt;triggerBody()['text']['minutes_text']&lt;/code&gt; cannot be evaluated&lt;/strong&gt;&lt;br&gt;
Cause: Agent flow triggers have a different body structure than Power Automate triggers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;③ Property 'minutes_text' doesn't exist, available properties are 'text'&lt;/strong&gt;&lt;br&gt;
Cause: The correct reference is &lt;code&gt;triggerBody()['text']&lt;/code&gt;, not nested further.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;④ Invalid or missing value for parameter: 'model'&lt;/strong&gt;&lt;br&gt;
Cause: &lt;code&gt;gpt-4o&lt;/code&gt; isn't a valid model ID for LDX hub. The correct format is &lt;code&gt;anthropic/claude-sonnet-4-6&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⑤ Invalid or missing value for parameter: 'example_output'&lt;/strong&gt;&lt;br&gt;
Cause: &lt;code&gt;example_output&lt;/code&gt; is required. I'd omitted it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⑥ The request body contains invalid or malformed JSON&lt;/strong&gt;&lt;br&gt;
Cause: The &lt;code&gt;inputs&lt;/code&gt; parameter isn't a string — it's an array of objects with a specific schema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⑦ Property 'output' doesn't exist, available properties are 'results, job_id, ...'&lt;/strong&gt;&lt;br&gt;
Cause: The results field is called &lt;code&gt;results&lt;/code&gt;, not &lt;code&gt;output&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⑧ Variable 'job_status' of type 'String' cannot be updated with value of type 'Array'&lt;/strong&gt;&lt;br&gt;
Cause: &lt;code&gt;results&lt;/code&gt; is an array. The variable holding it needs to be typed as Array, not String. Needed a separate String variable for the status field.&lt;/p&gt;




&lt;h2&gt;
  
  
  The working request body
&lt;/h2&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;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"anthropic/claude-sonnet-4-6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"system_prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Extract action items from the meeting minutes. Return assignee, task, and deadline in structured format."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"example_output"&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;"action_items"&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="nl"&gt;"assignee"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tanaka"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"task"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Prepare the report"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"deadline"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"End of May"&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;span class="nl"&gt;"inputs"&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="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"data"&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;"minutes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@{triggerBody()['text']}"&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;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;Key differences from what I'd been trying:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;inputs&lt;/code&gt; is an array of &lt;code&gt;{id, data}&lt;/code&gt; objects, not a plain string&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;model&lt;/code&gt; requires the provider-prefixed format: &lt;code&gt;anthropic/claude-sonnet-4-6&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;example_output&lt;/code&gt; is mandatory&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;triggerBody()['text']&lt;/code&gt; is the correct reference in agent flows&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The result
&lt;/h2&gt;

&lt;p&gt;Input: meeting minutes with three action items, including one with a vague deadline ("next week").&lt;/p&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Assignee&lt;/th&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Deadline&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Tanaka&lt;/td&gt;
&lt;td&gt;Prepare demo environment&lt;/td&gt;
&lt;td&gt;May 8, 2026 (Fri)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Suzuki&lt;/td&gt;
&lt;td&gt;Create job posting&lt;/td&gt;
&lt;td&gt;End of May 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Yamada&lt;/td&gt;
&lt;td&gt;Confirm October all-hands schedule&lt;/td&gt;
&lt;td&gt;End of June 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note appended by the model: &lt;em&gt;"Next week" was interpreted as May 8 (Friday) based on the meeting date of May 1, 2026. Please confirm if this is correct.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The model didn't just extract — it resolved ambiguity and surfaced its assumption. That's useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'd tell someone starting this today
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trap&lt;/th&gt;
&lt;th&gt;What to do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Browser back button&lt;/td&gt;
&lt;td&gt;Deletes unsaved flows. Save constantly.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP connector confusion&lt;/td&gt;
&lt;td&gt;Use the green built-in HTTP, not the white Office 365 one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flow not appearing in Copilot Studio&lt;/td&gt;
&lt;td&gt;Build from Agent flows inside Copilot Studio, not from Power Automate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;triggerBody() reference&lt;/td&gt;
&lt;td&gt;In agent flows: &lt;code&gt;triggerBody()['text']&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;inputs format&lt;/td&gt;
&lt;td&gt;Array of &lt;code&gt;{id, data}&lt;/code&gt; objects, not a plain string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model name&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;anthropic/claude-sonnet-4-6&lt;/code&gt;, not &lt;code&gt;gpt-4o&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;example_output&lt;/td&gt;
&lt;td&gt;Required. Don't skip it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Result field&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;results&lt;/code&gt;, not &lt;code&gt;output&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Time and honest assessment
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Total setup time: ~3 hours&lt;/strong&gt; (across both parts)&lt;/p&gt;

&lt;p&gt;An engineer would probably finish this in 30 minutes. For a non-engineer, 3 hours. Most of the errors were preventable by reading the API documentation first — which I didn't do carefully enough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What worked well once running:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Natural language input → structured JSON output&lt;/li&gt;
&lt;li&gt;Ambiguity resolution with explicit flagging&lt;/li&gt;
&lt;li&gt;Claude Sonnet 4.6 as the processing model (Kawamura International uses Claude Team, so Microsoft picked it up automatically — mildly amusing)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What still needs work:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The polling loop adds latency. For a single record, StructFlow returns fast — but the Do until loop with 5-second delays adds overhead.&lt;/li&gt;
&lt;li&gt;Error handling is minimal. If the API call fails mid-loop, the flow times out silently.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;MCP connection. Same use case, different integration method. The comparison between REST API and MCP — setup effort, reliability, latency — is the next article.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Kawamura International is a translation and localization company documenting its AI process experiments in public. StructFlow, RefineLoop, RenderOCR — and whatever comes next.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>powerautomate</category>
      <category>ldxhub</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>A non-engineer CEO tried to connect Copilot Studio to LDX hub. Here's what happened.</title>
      <dc:creator>Kozo-KI</dc:creator>
      <pubDate>Thu, 07 May 2026 00:42:49 +0000</pubDate>
      <link>https://dev.to/kozo-ki/a-non-engineer-ceo-tried-to-connect-copilot-studio-to-ldx-hub-heres-what-happened-356k</link>
      <guid>https://dev.to/kozo-ki/a-non-engineer-ceo-tried-to-connect-copilot-studio-to-ldx-hub-heres-what-happened-356k</guid>
      <description>&lt;p&gt;I'm the CEO of a translation company. I'm not an engineer. I can read code, but I can't write it.&lt;/p&gt;

&lt;p&gt;That's the context for everything that follows.&lt;/p&gt;

&lt;p&gt;LDX hub recently launched plugins for n8n, Dify, and Copilot Studio, making it possible to call &lt;a href="https://ldxlab.io/ldxhub/structflow" rel="noopener noreferrer"&gt;StructFlow&lt;/a&gt; — their structured data extraction API — from no-code workflow tools. I decided to try it myself instead of delegating.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spoiler: it's not working yet.&lt;/strong&gt; But I'm publishing this anyway, because a record of where things broke is more useful than a "it all went smoothly" writeup.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I was trying to build
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Goal:&lt;/strong&gt; An agent in Copilot Studio that takes meeting minutes as input and returns structured action items.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Microsoft Copilot Studio (agent)&lt;/li&gt;
&lt;li&gt;Power Automate (flow / middleware)&lt;/li&gt;
&lt;li&gt;LDX hub StructFlow (REST API)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Approach:&lt;/strong&gt; REST API first. If that works, compare with MCP.&lt;/p&gt;




&lt;h2&gt;
  
  
  The architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User (Copilot Studio chat)
    ↓  pastes meeting minutes
Power Automate flow
    ↓  POST to StructFlow API
LDX hub StructFlow
    ↓  returns structured JSON
Power Automate flow
    ↓  passes result back
User (receives action items)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Straightforward on paper. Less so in practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building the Power Automate flow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Finding the right trigger
&lt;/h3&gt;

&lt;p&gt;Opened &lt;a href="https://make.powerautomate.com" rel="noopener noreferrer"&gt;make.powerautomate.com&lt;/a&gt;, selected "Instant cloud flow."&lt;/p&gt;

&lt;p&gt;First blocker: &lt;strong&gt;"Power Virtual Agents" trigger wasn't visible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There was no search box on the trigger selection screen. I scrolled through the list and eventually found it. The label was slightly different from what the documentation described. Found it, selected it, moved on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Input variable
&lt;/h3&gt;

&lt;p&gt;Added a text input variable called &lt;code&gt;minutes_text&lt;/code&gt; to the trigger. No issues here.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP action
&lt;/h3&gt;

&lt;p&gt;Added "Send an HTTP request" and configured:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;URI:&lt;/strong&gt; &lt;code&gt;https://your-ldxhub-host.d2.zuplo.dev/structflow/jobs&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Method:&lt;/strong&gt; POST&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Header:&lt;/strong&gt; &lt;code&gt;Authorization: Bearer {API_KEY}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Second blocker: &lt;strong&gt;the header field format.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of separate "key" and "value" fields, this action uses a single text field per header, formatted as &lt;code&gt;HeaderName: HeaderValue&lt;/code&gt;. So the Authorization header goes in as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Authorization: Bearer your-api-key-here
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not obvious if you're used to other HTTP tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Polling loop
&lt;/h3&gt;

&lt;p&gt;StructFlow is asynchronous. You POST a job, get back a &lt;code&gt;job_id&lt;/code&gt;, and need to poll until &lt;code&gt;status: "completed"&lt;/code&gt; before you can retrieve results.&lt;/p&gt;

&lt;p&gt;In Power Automate, this means a &lt;strong&gt;Do until&lt;/strong&gt; loop. The structure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Initialize variable &lt;code&gt;job_id&lt;/code&gt; (string)&lt;/li&gt;
&lt;li&gt;Set variable — extract &lt;code&gt;job_id&lt;/code&gt; from HTTP response&lt;/li&gt;
&lt;li&gt;Delay 5 seconds&lt;/li&gt;
&lt;li&gt;Initialize variable &lt;code&gt;job_status&lt;/code&gt; (string)&lt;/li&gt;
&lt;li&gt;Do until loop:

&lt;ul&gt;
&lt;li&gt;GET request to check job status&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;job_status&lt;/code&gt; from response&lt;/li&gt;
&lt;li&gt;Stop condition: &lt;code&gt;job_status&lt;/code&gt; equals &lt;code&gt;completed&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Return result to Copilot Studio&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Third blocker: &lt;strong&gt;the browser back button deletes your flow.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hit the back button before saving. The flow was gone. Started over.&lt;/p&gt;

&lt;p&gt;Lesson: &lt;strong&gt;save constantly in Power Automate.&lt;/strong&gt; There's no autosave equivalent to what you'd expect from a modern web app.&lt;/p&gt;

&lt;p&gt;The Do until condition also caused an error when I tried to reference &lt;code&gt;job_status&lt;/code&gt; via the GUI. Fixed it by switching to "Edit in advanced mode" and typing the expression directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="k"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job_status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'completed'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The flow eventually completed. Green banner: "Your flow is ready to run."&lt;/p&gt;




&lt;h2&gt;
  
  
  Connecting to Copilot Studio
&lt;/h2&gt;

&lt;p&gt;Created an agent called "Minutes Assistant" in Copilot Studio.&lt;/p&gt;

&lt;p&gt;Observation: &lt;strong&gt;the default model was Claude Sonnet 4.6.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our company uses Claude Team, so Microsoft apparently picked it up automatically. Our enterprise agent running on Claude — mildly amusing given the context of this article.&lt;/p&gt;

&lt;p&gt;Now for the main blocker: &lt;strong&gt;the Power Automate flow didn't appear in Copilot Studio's tool list.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Same environment, same account. The flow just wasn't visible. I tried searching, browsing the Workflow tab — nothing.&lt;/p&gt;

&lt;p&gt;Explored the sidebar and found "Flows" → "Agent flows" — a feature where you describe what you want in natural language and AI generates a flow. The AI generated something instantly, but the action it created pointed to an unrecognizable internal ID — certainly not the StructFlow API in any recognizable form.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where things stand
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Power Automate flow&lt;/td&gt;
&lt;td&gt;✅ Built&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Do until polling loop&lt;/td&gt;
&lt;td&gt;✅ Working&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copilot Studio connection&lt;/td&gt;
&lt;td&gt;❌ Unresolved&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent flow AI generation&lt;/td&gt;
&lt;td&gt;⚠️ Generated, not verified&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What tripped me up:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No autosave&lt;/strong&gt; — browser back = flow gone&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single-field header format&lt;/strong&gt; — &lt;code&gt;Key: Value&lt;/code&gt; in one box, not two&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flow not visible in Copilot Studio&lt;/strong&gt; — same environment, still not showing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-generated flow&lt;/strong&gt; — unclear what API it's actually calling&lt;/li&gt;
&lt;/ol&gt;




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

&lt;ul&gt;
&lt;li&gt;Inspect the AI-generated agent flow to see what it's actually calling&lt;/li&gt;
&lt;li&gt;Test whether StructFlow is being invoked correctly&lt;/li&gt;
&lt;li&gt;If it works: run it against real meeting minutes&lt;/li&gt;
&lt;li&gt;Part 2 will cover the full resolution (and MCP comparison)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll publish the follow-up when it actually works. This one ends here — unresolved, on purpose.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Kawamura International is a translation and localization company. We're documenting our AI process experiments as we go — StructFlow, RefineLoop, RenderOCR, and whatever comes next.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>powerautomate</category>
      <category>ldxhub</category>
      <category>ai</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>"The CEO Wrote This with MCP" — How I Used an AI Agent to Examine the Translation Industry's Pain Points</title>
      <dc:creator>Kozo-KI</dc:creator>
      <pubDate>Fri, 01 May 2026 04:17:30 +0000</pubDate>
      <link>https://dev.to/kozo-ki/the-ceo-wrote-this-with-mcp-how-i-used-an-ai-agent-to-examine-the-translation-industrys-pain-1f20</link>
      <guid>https://dev.to/kozo-ki/the-ceo-wrote-this-with-mcp-how-i-used-an-ai-agent-to-examine-the-translation-industrys-pain-1f20</guid>
      <description>&lt;p&gt;&lt;em&gt;Kawamura International / LDX Lab&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Starting with the Pain Points
&lt;/h2&gt;

&lt;p&gt;There are some quietly troublesome problems in the translation field.&lt;/p&gt;

&lt;p&gt;When IR or legal documents are run through a general-purpose MT system, number formatting falls apart. Honorific language does not match the writing style. Company-specific terminology gets replaced with different translations. The feeling of "Having to fix this again?" can end up accounting for most of the post-translation work.&lt;/p&gt;

&lt;p&gt;This is less a problem with translation tools than a limitation of processing unstructured text without context. The same thing happens with meeting minutes. Who is supposed to do what by when is buried in the text, and you cannot tell unless you read it.&lt;/p&gt;

&lt;p&gt;What I set out to do today was test what would happen if that process were handed over to an AI agent.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Background
&lt;/h2&gt;

&lt;p&gt;Let me be honest from the start. &lt;strong&gt;I am not an engineer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We have a CTO. We also have people who can read code. But I conducted today's test entirely on my own. What I used was the Claude.ai chat interface and our in-house API (LDX hub), connected via MCP. I did not write a single line of code.&lt;/p&gt;

&lt;p&gt;This also serves as a record of where non-engineers get stuck when using AI agents.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture: Connecting APIs with MCP
&lt;/h2&gt;

&lt;p&gt;The setup is simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claude (chat)
  └── Zuplo MCP (API gateway)
        └── LDX hub
              ├── StructFlow   ← Turns unstructured text into structured JSON
              ├── RefineLoop   ← Post-translation terminology and quality refinement
              └── RenderOCR    ← Text extraction from PDFs and images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LDX hub is an API service developed in-house. It handles translation, OCR, and data structuring. It runs on an API gateway called Zuplo, and Zuplo has MCP server functionality.&lt;/p&gt;

&lt;p&gt;In other words, &lt;strong&gt;if you connect Zuplo MCP to Claude, Claude itself will decide when to call the API&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting It Connected (Where I Got Stuck)
&lt;/h2&gt;

&lt;p&gt;The connection process has three steps.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate an API key in the Zuplo dashboard&lt;/li&gt;
&lt;li&gt;Add the MCP server in Claude.ai settings (URL + API key)&lt;/li&gt;
&lt;li&gt;Verify the connection&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It looked simple, but &lt;strong&gt;I got stuck at step 1.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It wasn't immediately obvious where in the Zuplo dashboard to generate the key. I ended up reading through the documentation to find it. Later, while doing the VOC analysis (described below), I came across a user review that described exactly the same experience:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Honestly struggled with the initial setup.
 Figuring out that API keys are issued from the Zuplo
 dashboard wasn't obvious. But once it was running,
 StructFlow's accuracy was satisfying."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was one of the fictional review data items I processed with StructFlow today, but it felt very real. I'll make a tutorial video.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verification 1: Extracting Action Items from Meeting Minutes
&lt;/h2&gt;

&lt;p&gt;The first thing I tried once connected was structuring meeting minutes.&lt;/p&gt;

&lt;p&gt;I simply described what I wanted: "Please extract the person responsible, the task, and the deadline from five sets of meeting minutes."&lt;/p&gt;

&lt;p&gt;Claude assembled the job on its own.&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;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"anthropic/claude-sonnet-4-6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"system_prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Extract all action items from the meeting minutes..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"example_output"&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;"action_items"&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="nl"&gt;"assignee"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tanaka"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"task"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fix the bug"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"due_date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-05-02"&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;span class="nl"&gt;"inputs"&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="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"minutes-001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"data"&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;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;All&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;submitted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;once&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;I did not write any of this JSON. Claude selected the &lt;code&gt;createStructFlowJob&lt;/code&gt; tool on its own and called it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result: 13 action items extracted from 5 sets of minutes in 11 seconds. 100% success rate.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What I found interesting: from the sentence "Tanaka will fix this by April 22. (Note: confirmed as already resolved as of today)," it separately extracted the deadline and the completion flag. It is reading context, not simply extracting keywords.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verification 2: VOC Analysis of 100 Reviews
&lt;/h2&gt;

&lt;p&gt;Next, I tried a VOC (Voice of Customer) analysis of app reviews.&lt;/p&gt;

&lt;p&gt;When I said "I want to analyze 100 mixed Japanese-English reviews for a task management app tentatively called Flowra," Claude:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generated the 100 review data items itself (70 in Japanese, 30 in English)&lt;/li&gt;
&lt;li&gt;Submitted 2 parallel jobs to StructFlow&lt;/li&gt;
&lt;li&gt;Once the results came back, formatted them into an HTML report&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All I did was describe what I wanted in three sentences.&lt;/p&gt;

&lt;p&gt;The five fields it extracted per review:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Each review → StructFlow → Structured JSON
               ├─ sentiment (positive / negative / neutral)
               ├─ nps_score (integer 0–10)
               ├─ evaluation_axes (axis / score / comment)
               ├─ mentioned_features (feature names mentioned)
               └─ improvement_requests (requested improvements)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result: All 100 items completed successfully. Processing time was 69 seconds for Job 1 and 59 seconds for Job 2. Output character count was 4.3× the input (33,791 characters).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The 4.3× figure is because comments are automatically generated for each evaluation axis, not simply classified. Something like "Ease of use: Task management has genuinely become easier (positive)" is generated for 100 items across multiple axes.&lt;/p&gt;

&lt;p&gt;When I aggregated the data, a polarization emerged: 37% were promoters (NPS 9–10), and 37% were also detractors (0–6). It is a typical product pattern where dissatisfaction with pricing coexists with enthusiasm for features.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Noticed: What "Understanding Intent" Actually Means
&lt;/h2&gt;

&lt;p&gt;The key thing I realized from spending the day on this: once MCP gives Claude access to tools, &lt;strong&gt;Claude decides on its own how to call them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I had not read the StructFlow API reference. I had no idea how to submit jobs. But it called &lt;code&gt;createStructFlowJob&lt;/code&gt;, polled with &lt;code&gt;getStructFlowJob&lt;/code&gt;, and moved on once the job was done.&lt;/p&gt;

&lt;p&gt;This is different from code completion. It is decomposing a task and executing autonomously within the constraints of the tools.&lt;/p&gt;

&lt;p&gt;However, there is a prerequisite. &lt;strong&gt;The tool schema must be accurately defined.&lt;/strong&gt; Because Zuplo exposes parameters accurately, Claude can pass the correct arguments. If the schema is ambiguous, things stop before "understanding intent" even becomes relevant.&lt;/p&gt;




&lt;h2&gt;
  
  
  Honest Assessment
&lt;/h2&gt;

&lt;p&gt;What worked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once I described what I wanted, Claude handled job assembly, submission, polling, and formatting&lt;/li&gt;
&lt;li&gt;Quality did not drop even with mixed Japanese-English text&lt;/li&gt;
&lt;li&gt;Even as a non-engineer, once connected, I was able to produce something that actually works&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What did not work / areas for improvement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Initial setup takes real effort.&lt;/strong&gt; The API key location in particular was not obvious&lt;/li&gt;
&lt;li&gt;I ended up pasting an API key into the chat, which was a security issue (I reissued it immediately)&lt;/li&gt;
&lt;li&gt;Direct calls to the Anthropic API from the browser were blocked by CORS (I worked around it a different way)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am including the failures here. A record of where things broke is more reproducible than a "everything went perfectly" account.&lt;/p&gt;




&lt;h2&gt;
  
  
  Today's Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Verification&lt;/th&gt;
&lt;th&gt;Volume&lt;/th&gt;
&lt;th&gt;Processing Time&lt;/th&gt;
&lt;th&gt;Success Rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Meeting minutes → Action items&lt;/td&gt;
&lt;td&gt;5 items&lt;/td&gt;
&lt;td&gt;11 seconds&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reviews → VOC structuring&lt;/td&gt;
&lt;td&gt;100 items&lt;/td&gt;
&lt;td&gt;69s + 59s&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In both cases, all I did was describe what I wanted.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"Isn't plain LLM enough?" — put to the test&lt;/strong&gt;: Comparing the same 100 minutes submitted directly to the Anthropic API (Part 2)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;MCP takes a bit of effort to get connected. But once it's connected, Claude takes over. &lt;strong&gt;All you need to do is tell it what you want. That holds true even for non-engineers.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;LDX Lab case studies: &lt;a href="https://ldxlab.io/ldxhub/case" rel="noopener noreferrer"&gt;https://ldxlab.io/ldxhub/case&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;a href="https://ldxlab.io/ldxhub/structflow" rel="noopener noreferrer"&gt;StructFlow&lt;/a&gt; / &lt;a href="https://ldxlab.io/ldxhub/refineloop#pipeline" rel="noopener noreferrer"&gt;RefineLoop&lt;/a&gt; / RenderOCR / TermWeave (coming soon)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>mcp</category>
      <category>nlp</category>
    </item>
  </channel>
</rss>
