Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
輸入実行関税率表をMCPサーバー化してみた
Search
Qlitre
September 11, 2025
550
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
輸入実行関税率表をMCPサーバー化してみた
Qlitre
September 11, 2025
More Decks by Qlitre
See All by Qlitre
microCMS × Hono:飯ログ店舗を自作MCPサーバーでAI登録
qlitre
0
1k
Featured
See All Featured
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
390
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.7k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
570
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1k
Design in an AI World
tapps
1
350
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Believing is Seeing
oripsolob
1
240
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
510
Leo the Paperboy
mayatellez
10
2.3k
A Tale of Four Properties
chriscoyier
163
24k
Mind Mapping
helmedeiros
1
390
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Transcript
!LVSJ@UUFSɹ ༌ೖ࣮ߦؔ੫දΛ .$1αʔόʔԽͯ͠Έͨ
ࣗݾհ ͘Γͬͨʔ w 9 !LVSJ@UUFS ɹIUUQTRMJUSFNF w ࣄ w ߓྲྀݿاۀ
w ݱಜɺྫྷౚݿӦۀͳͲΛܦͯݱࡏ*5ௐୡ w ϓϩάϥϛϯά w झຯͰ)POP 1ZUIPOͳͲɻ w 8PSLFSTY)POP9ͰݸਓϒϩάͳͲެ։ ݄ାʹͯ
࣍ w ༌ೖ࣮ߦؔ੫දʹ͍ͭͯ w .$1࣮֓ཁ w σϞ w ධՁ
༌ೖ࣮ߦؔ੫දʹ͍ͭͯ
༌ೖ՟͕ྲྀ௨͢Δ·Ͱ ւ֎ อ੫Ҭ ʢ֎ࠃ՟Λஔ͚Δॴʣ ɾίϯςφϠʔυ ɾۭߓ ɾྲྀݿɹʜFUD ࠃ ࢢ ༌ૹɾൖೖ
ൖग़ ༌ೖ ਃࠂ ੫ؔ ৹ࠪ ࠃ ؔ੫ ೲ ༌ೖ ڐՄ ͜͜Ͱར༻͢Δͷ͕༌ೖ࣮ߦؔ੫දʢλϦϑʣ ՙओʢࣾɾϝʔΧʔʣ͕ ྲྀۀऀʹ༌ೖਃࠂखଓ͖ Λҕୗ͢Δͷ͕Ұൠతɻ
w ༌ೖ͞ΕΔશͯͷʹ͍ͭ ͯɺܻ̕ͷ౷ܭ൪߸ͱؔ੫ ΛఆΊͨҰཡද w ̓̕ΧςΰϦͰߏ w ༌ೖਃࠂ࣌ʹඞཁͳؔ੫Λௐ ΔͨΊͷඞਢπʔϧ w
੫ؔ8&#Ͱແྉެ։ɻ w ʮ༌ೖ࣮ߦؔ੫දʯͰ͙͙Δ ͱҰ൪্ʹग़ͯ͘Δ ༌ೖ࣮ߦؔ੫දʢλϦϑʣͱʁ IUUQTXXXDVTUPNTHPKQUBSJ ff @@JOEFYIUN
ύελͷ༌ೖ੫൪Λಛఆ͢Δ߹ (15Ͱੜ
ύελখഴคͰग़དྷ͍ͯΔɻୈྨΛΈΔɻ
ʹʼʹ֘ɹؔ੫جຊԁLH850ՃໍࠃԁLH ੫ϦϯΫΛ։͘ͱIUNMςʔϒϧ͕͋Γɺৄࡉͳ͕ܝࡌ
w ίʔυ छྨఔ͋ΓɺਓྗͰͷಛఆ͚ͬ͜ ͏͕͔͔࣌ؒΔɻ w ༌ೖ݅૿Ճɻͷຊʹ͓͚Δ༌ೖਃࠂ݅ ɺߤۭɾւ্Λซͤԯ ສ݅ w ʢࢀߟɿIUUQTXXXOBDDTKQBSDIJWFTVOLZPV
TIJSZPQEGʣ ՝ͱϞνϕʔγϣϯ ϦϞʔτ.$1αʔόʔԽ͢Εͷಛఆޮ ԽͰ͖ͦ͏ͳؾ͕ͨ͠ɻ ॻ੶͋Δɻ ஈɿ ԁ
.$1࣮֓ཁ
༌ೖ࣮ߦؔ੫දΛσʔλԽ IPOPNDQϔϧύʔͰΩʔϫʔυݕࡧΛ࣮ $MPVE fl BSF8PSLFSTʹσϓϩΠ ࣮ͷ֓ཁ
ߏɻDTWΑΓKTPO
1ZUIPOͷ#FBVUJGVMTPVQͰ8&#εΫϨΠϐϯάͯ͠σʔλԽ UETUZMFlQBEEJOHMFGUFNzύελʢՃʹΑΔௐཧΛʜʣUE-&7&- UETUZMFlQBEEJOHMFGUFNͦͷଞͷͷUE-&7&- UETUZMFQBEEJOHMFGUFNͦͷଞͷͷUE-&7&- UETUZMFQBEEJOHMFGUFN - ϚΧϩχٴͼεύήοςΟUE-&7&- ࢠؔʢʹͷਂ͞ʣIUNMTUZMFͷQBEEJOHͷͱlzͰఆ def extract_level(td)
-> int: """style="padding-left:…em" ͔Β֊ϨϕϧΛͰฦ͢""" # paddingͷΛൈ͖ग़͢ m = re.search(r"padding-left\s*:\s*([\d.]+)\s*em", td.get("style", "")) level = int(float(m.group(1))) if m else 0 # - ͷΛ͑Δ cnt = 0 for c in td.text.strip(): if c == "−": cnt += 1 else: break return level + cnt
هͨ͠-&7&- ਂ͞ʣΛݩʹೖΕࢠɺΛදݱɻ { "level": 0, "stat_code": "19.02", "desc": "ύελྨɾΫʔεΫʔε", "children":
[ { "level": 1, "stat_code": "19.02", "desc": "ύελʢௐཧɾௐ͍ͯ͠ͳ͍ͷʣ", "children": [ { "level": 2, "stat_code": "1902.19", "desc": "ͦͷଞͷͷ", "children": [ { "level": 3, "stat_code": "1902.19", "desc": "ͦͷଞͷͷ", "children": [ { "level": 4, "desc": "ϚΧϩχٴͼεύήοςΟ", "children": [ { "level": 5, "stat_code": "1902.19", "hs_code": "093", "desc": "εύήοςΟ" } ] } ] } ] } ] } ] }
̍ྨɿಈʢੜ͖͍ͯΔͷʹݶΔʣʙ̓̕ྨɿඒज़ɺऩूٴͼͭ͜ͱ͏
)POPϓϩδΣΫτʹKTPOΛஔɻ γϯϓϧͳΩʔϫʔυݕࡧͰ)POPNDQͰ8PSLFSTʹσϓϩΠɻ DPOTUBQQOFX)POP BQQBMM BTZOD D \ DPOTUNDQ4FSWFSBXBJUHFU.DQ4FSWFS
D DPOTUUSBOTQPSUOFX4USFBNBCMF)5515SBOTQPSU BXBJUNDQ4FSWFSDPOOFDU USBOTQPSU SFUVSOUSBOTQPSUIBOEMF3FRVFTU D ^ export const getMcpServer = async (c: Context<Env>) => { const server = new McpServer({ name: "japan-tariff-mcp", version: "0.0.1", }); server.tool( "searchTariffByKeywords", "Search tariff data by keywords (comma-separated)", { keywords: z.string().min(1) }, async ({ keywords }) => { const { results, hitCount } = await searchService.searchTariffData( keywords ); const limit = 30; let msg = ""; if (results.length > limit) { msg = `More than the maximum limit of ${limit} items were found. Please refer to hitCount and re-search if necessary.`; } return { content: [ { type: "text", text: JSON.stringify({ message: msg, hitCount: hitCount, results: results.slice(0, limit), }), }, ], }; } ); }; ۪ͳઢܗ୳ࡧɻݸͷKTPO ϑΝΠϧΛॱ൪ʹ։͖จࣈ͕ ؚ·ΕΔ͔ఆɻ )POPNDQͰ৴
w ੈʹʮ8&#λϦϑʯͱݺΕΔެ ࣜݕࡧαΠτଘࡏ͢Δɻ w ໊͕ͦͷ··ࡌ͍ͬͯͳ͍έ ʔεଟ͍ɻ w ྫ͑νϡʔϋΠͰݕࡧͯ͠ώ οτ͠ͳ͍ɻ w
.$1νϡʔϋΠ মய Ξϧίʔ ϧҿྉͱʮΑ͠ͳʹʯྨޠݕࡧɻ w ݟ͔ͭΔ·ͰʮؤுΔʯɻ .$1ݕࡧπʔϧͷಛͱ௨ৗͱͷҧ͍
w ͱͱ୯ҰͷΩʔϫʔυͰ࣮ɻ w ݕࡧˠݟ͔ͭΒͳ͍ˠݕࡧʜͱ܁Γ ฦ͢ͷ͕ɻ w ΩʔϫʔυΛΧϯϚ۠ΓͰड͚औ ΔΑ͏ʹҙॻ͖ɻ w zνϡʔϋΠ
মய Ξϧίʔϧҿྉz ͱ͍͏จࣈྻΛ"*͕ͯ͘͠ΕΔɻ w ϩδοΫଆͰTQMJUͯ͠Ұ୯ޠͣͭ ఆɻࢼߦճΛେ෯ʹݮɻ ᶃɹݕࡧΩʔϫʔυΛΧϯϚ۠ΓͰड͚औΔ server.tool( // ΧϯϚ۠ΓͰड͚औΔΑ͏ʹ͢Δ "searchTariffByKeywords", "Search tariff data by keywords (comma-separated)", { keywords: z.string().min(1) }, async ({ keywords }) => { // ϩδοΫଆͰsplitͯ͠ώοτఆ const { results, hitCount } = await searchService.searchTariffData( keywords ); ɹɹɹ…লུ );
w ྫʣϑϥΠυνΩϯˠʮௐʯ͕ ݅ɺʮܲʯ݅ɻ ʢzௐ৯ྉz͔Β࿈ʣ w Ωʔϫʔυ͝ͱͷώοτ݅Λه ͯ͠"*ʹฦ͢ɻ w ্ݶΛ͑ͨΒɺ݅Λࢀߟʹ ࠶ݕࡧΛࢹʹೖΕΔɻ
w ΠΠײ͡ʹيಓमਖ਼ͯ͠ߜΓ͜Μ Ͱ͘ΕΔΑ͏ʹͳͬͨɻ ᶄɹҙਤ͠ͳ͍Ωʔϫʔυ͕ώοτͨ͠߹ͷيಓमਖ਼ server.tool( …ɹলུ async ({ keywords }) => { // ݕࡧΩʔϫʔυ͝ͱͷώοτ݅Λड͚औΔΑ͏ʹ͢Δ const { results, hitCount } = await searchService.searchTariffData( keywords ); // ώοτͷ্ݶΛઃఆ const limit = 30; let msg = ""; // ্ݶΛ͑ͯͨΒɺඞཁʹԠͯ͡࠶ݕࡧΛ͢Δ if (results.length > limit) { msg = `More than the maximum limit of ${limit} items were found. Please refer to hitCount and re-search if necessary.`; } return { // ϝοηʔδͱώοτ݅Λ݁Ռʹฦ͢ content: [ { type: "text", text: JSON.stringify({ message: msg, hitCount: hitCount, results: results.slice(0, limit), }), }, ], }; } );
None
σϞ
ධՁ
w γϯϓϧͳϓϩάϥϜ͕ͩɺް͍λϦϑදΛΊ͘Δखؒল͚Δ w ࣾͷ༗ࣝऀʢ௨ؔ࢜ʣʹͬͯΒͬͨͱ͜Ζײ৮ͩͬͨɻ w ˋٻΊͣௐࠪͷऔֻ͔ͬΓͰ͑Εे༗༻ɻ w ίετ΄΅͔͔Βͳ͍ͱࢥΘΕΔɻ ධՁ
w HJUIVCൃදݩͱͳͬͨιʔείʔυશจ w IUUQTHJUIVCDPNRMJUSFKBQBOUBSJ ff NDQ
͋Γ͕ͱ͏͍͟͝·ͨ͠