FORRT Research について
FORRT Researchは、再現、追試、新規研究のための検証可能なFORRT nanopublicationチェーンを構築する研究者向けMCPサーバーです。PDFの引用を確認し、チェーンや先行研究、テンプレート、語彙の情報を提供します。
主な機能
- 01PDF本文との引用照合と段階判定
- 02nanopublicationグラフを読みやすいチェーンに投影
- 03先行研究の主張と結果の取得
- 04テンプレート項目と制御語彙の参照
- 05研究モードに応じたチェーン検証
活用シーン
- 01nanopublication公開前の引用確認
- 02新規研究前の先行主張と限界の調査
- 03チェーン作成時の有効な項目と値の確認
MCP 対応
引用検証、チェーン確認、先行研究の検索、テンプレートと語彙の取得などの研究ツールをMCPクライアントに提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx forrt-research-mcpSCIENCELIVE_API_BASEScience Live API base URL (default: https://api.sciencelive4all.org)SCIENCELIVE_API_KEYシークレットScience Live API key; optional, /np/constellation is a public readローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
13掲載時のツール一覧 · 3 日前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| uri | string | はい | |
| depth | integer | いいえ | |
| max_nodes | integer | いいえ |
詳細
forrt-research-mcp
検証可能な FORRT ナノパブリケーションチェーンを作成するための MCP サーバーです。研究者が作業を探すときではなく、実際に作業を進めるときに必要なツールを提供します。再現、追試、ゼロから始める研究という3種類の研究を、同じ仕組みで支援します。
連携する3つのサーバーのうち、3番目のサーバーです。
| サーバー | 答える問い |
|---|---|
| OpenAIRE MCP | 文献には何が書かれていますか? |
replication-radar | 追試する価値のある研究はどれで、すでに追試されていますか? |
forrt-research-mcp | 正確で検証可能なチェーンを作成するには、どうすればよいですか? |
forrt-replication-templateのワークフロー向けに構築されていますが、このリポジトリの機能は必要ありません。どのエージェントからでも呼び出せます。
範囲:再現、複製、ゼロからの研究
この3つはいずれもここで扱われ、同じチェーンを使用します。
anchor → AIDA → Claim → Study → Outcome → CiTO
ステップ01には3つのアンカーがあり、同じ形式のバリエーションではありません。 どのアンカーが適切かは、その研究が再現、複製、オリジナル研究のいずれであるかとは無関係です。
| アンカー | 必須フィールド | 備考 |
|---|---|---|
01_quote 引用とコメント | paper、quotation、comment | typeもlabelもありません。quotationは500文字、commentは800文字までです。制限は文章中ではなく、テンプレート独自の正規表現で定められています |
01_pico PICOの質問 | label、description、type、+ P/I/C/Oの説明 | 質問タイプの語彙(5つの用語)がある唯一のアンカーです |
01_pcc PCCの質問 | label、description、+ P/C/Cの説明 | typeフィールドは一切ありません |
3つには共通するフィールドIDがひとつもないため、同じものだと決めつけず、実際に使用しているアンカーに対してtemplate_fieldsを呼び出してください。pico_question_typeという語彙名がPICOにちなんでいるのは意図的です。PCCの質問には参照するtypeがありません。
verify_quoteはQuoteアンカーにのみ適用されます。引用はレビューではなく正しさを証明できる唯一のフィールドであるため、専用ツールがあるのもこのアンカーだけです。
constellationとprior_workは、framework、label、質問全文、およびそのフレームワークのcomponentsを含む質問アンカーを提示します。PICOではpopulation/intervention/comparator/outcome、PCCではpopulation/concept/contextです。質問ノードはこれらすべてをquestionオブジェクトに保持し、トップレベルのlabelは空にするため、引用のように読み取ると何も返されません。実際に公開された2つの質問ナノパブに対してテスト済みです。
ゼロから始める研究では、Claimは独自の仮説であり、自分自身の質問、または基盤とする研究から導き出されます。FORRT Claimテンプレートではsourceは任意なので、外部の論文は不要です。そのため、ClaimがStudyより前に来る順序は、食い違いではなく事前登録として解釈できます。verify_chainはmode(auto/replication/reproduction/new_research)を受け取り、必須要件だけを変更します。ゼロからの研究には引用する既存研究がないため、CiTOステップも引用DOIも期待されません。
テンプレートがいまだに原著研究を前提としているのは、04_studyにあるstudy_type語彙だけです。その3つの用語はすべて複製を前提としたものです(Replication Study、Reproduction Study、またはその両方)。独自のClaimを検証するオリジナル研究を表す用語はありません。また、3つのフィールドプロンプトも不自然です。scopeとmethodologyには「再現/複製される」とあり、Outcomeのconclusionには「元のClaimについて」とあります。ただし、これらは文言の問題にすぎません。validationStatus(validated/partially supported/contradicted/inconclusive/not tested)は、独自の仮説の検証を問題なく表現できます。
したがって、このギャップを埋めるには、新しいテンプレート群ではなく、語彙用語を1つ追加し、プロンプトを3つ言い換えるだけで済む可能性が十分にあります。それが実現すれば、このサーバーはコード変更なしで対応できます。template_fieldsとvocabularyはライブで取得し、driftedFromSnapshotが上書きを検知するため、ベンダー提供のコピーを再生成できます。
ゼロから始める研究に「Reproduction Study」を使う場合の注意。 より適切な用語が語彙にない間の回避策としては妥当ですが、このテンプレートにおける意味は複製科学の用法、つまり「直接的な再現:同じ方法論、同じツール」です。これは、他者の分析を再実行することを指し、「自分の研究は再現可能である」というRSEの意味ではありません。下流の利用者は前者として解釈します。
replication-radarの判定オーバーレイとverified_claimsは、この研究を既存のClaimの検証として提示します。
サーバーであり、プロンプトではない理由
ここでの2つの作業は、推論のように見えますが、実際にはそうではありません。エージェントループで実行すると、再現性がなくなり、コストもかさみます。
1. 公開済みのチェーンを読む。 /np/constellation は FORRT の引用グラフを双方向にたどり、到達したものをすべて返します。単一の海洋熱波チェーンでも、330 KB、98 個のノード、1012 本のエッジで、そのうち 64 個のノードはまったく別の研究に属する AIDA ステートメントです。これをエージェントに渡すとコンテキストを消費し、別の論文の主張について推論するよう促してしまいます。constellation は同じチェーンを約 16 KB(4.7 %)で返します。
2. 引用が実在するか確認する。 FORRT Quote nanopub は逐語的でなければなりません。これは判断ではなく文字列検索なので、回答を覆すことのできないツールであり、誰でも再実行して同じ結果を得られるものであるべきです。
対応しないこと
論文の検索(それは OpenAIRE MCP の役割です)、複製対象の順位付け(それは replication-radar の役割です)、nanopub の内容の作成は行いません。また、主張の抽出も行いません。論文の主要な主張を含む文を選ぶのは判断であり、その判断をツールで包んでも再現可能にはなりません。ツールの境界の内側にあるモデルも、エージェントループ内のモデルと同じく非決定的です。このサーバーが基盤とする役割分担は次のとおりです。
| モデルが提案すること | このサーバーが判定すること |
|---|---|
| どの文が主張か | その文が PDF 内にあるか、どこにあるか、どの SHA-256 か |
| AIDA の表現方法 | テンプレートに実際にどのフィールドがあり、それぞれの上限がいくつか |
| どの主張タイプまたは CiTO 関係が当てはまるか | フォームが実際に受け付ける値 |
| どの Wikidata トピックを指しているか | その QID が存在し、適切なタイプであるか |
| どの論文を引用するか | その DOI が解決されるか、解決先はどこか |
| 先行研究を拡張するか、異議を唱えるか | 既存のチェーンがすでに何を主張しているか |
インストール
pipx install forrt-research-mcp
claude mcp add forrt-research -s user -- forrt-research-mcp
すべてのセッションとフォルダーで利用でき、リポジトリごとの設定と競合しないよう、ユーザースコープ(-s user)で設定します。他のエージェントでは、stdio コマンドは forrt-research-mcp です。
# optional
export SCIENCELIVE_API_BASE="https://api.sciencelive4all.org" # default (production)
export SCIENCELIVE_API_KEY="sl_…" # /np/constellation is a public read
デフォルトのベースは本番環境です。開発環境のデプロイに対してテストするには、
SCIENCELIVE_API_BASE=https://api-dev.sciencelive4all.orgを設定してください。最近リクエストされていない constellation は、構築に約 60 秒かかることがあります。その後は 4 時間キャッシュされ、1 秒もかからずに返されます。
ツール
verify_quote(pdf_path, quotation)
候補となる引用文が公開前に元の PDF に含まれていることを確認します。ページ、文字オフセット、ファイルの SHA-256 とともに、段階評価された判定を返します。
| 判定 | 意味 |
|---|---|
exact | 抽出されたページテキストとバイト単位で完全に一致します |
normalized | 空白/合字/組版上の句読点/行末ハイフンを修正した後に一致しました |
extraction_tolerant | さらにハイフンと句読点の間隔を無視して一致しました |
whitespace_insensitive | さらにすべての空白を削除して一致しました — テキストレイヤーで単語が分断されている場合に使います |
not_found | この PDF にはありません — 公開しないでください |
各段階で正規化するのは書式のみであり、単語、数字、語順は変更しません。数字を 1 つ変更した引用文は、元のテキストとの類似度が約 0.91 になっても not_found になります。一致しない場合、closest.text_in_pdf に論文に実際に記載されている内容が表示されます。
exact より下の段階になるのは通常のことです。PDF の抽出では改行が挿入されたり、ハイフンが失われたり、単語が完全に分断されたりします。
- 実際の海洋熱波のチェーンで公開された引用文は、
extraction_tolerantでのみ一致します。pypdfが論文の35-yearを35yearと読み取り、(p <を( p <と読み取るためです。 - Hundhausen et al. 2024 では、論文自体の要旨が
CP en semble、largest c hanges、prec ipitationのように表示されます。単語の内部に空白が入っており、句読点のルールでは修正できません。これには、すべての空白を削除するwhitespace_insensitiveが必要です。そのため単語の境界は検証されません。また、短いテキスト同士が偶然一致する可能性があるため、40 文字未満では実行されません。
抽出された PDF テキストに対する「一字一句の一致」は文字どおりには実現できません。そのため、結果は真偽値ではなく段階評価されます。
改行をまたいで分割された単語(convection-\npermitting)は、normalized 段階で再結合されます。一方、行末に残されたままのハイフン(15- and 30-minute)は意図的に再結合されません。このルールには改行が必要です。再結合するとテキストが損なわれるためです。
constellation(uri, depth=5, max_nodes=80)
公開済みの nanopub URI からたどれる FORRT チェーンを、エージェント向けのサイズに投影したものです。チェーンの各ステップはチェーン内の順序で示され、最上位の CiTO、Research Synthesis、およびこの論文に帰属する Quote/Question アンカーが含まれます。
API のトップレベルの paperDoi ではなく、citedPaper を参照してください。詳しくは、以下の上流の注意点をご覧ください。
stepsPresent で一部のステップが省略されるのは正常です。コンステレーションの最上位にある CiTO はチェーンから切り離され、Quote/AIDA アンカーが列挙されないこともよくあります。欠落していても、未公開とは限りません。
prior_work(uri)
ある論文について、これまでに何が主張されてきたかを示します。研究を新たに始める場合も、再現研究を行う場合も、ここが出発点になります。完了したチェーンごとに、主張の種類、scope、method、deviations、判定、確信度、リポジトリ、limitations が含まれます。
limitations は特に注意深く読むべきフィールドです。ここには、先行研究の著者が研究の対象外だった内容を、署名付きの改変不能な言葉で記しています。それは次の研究の出発点となることが少なくありません。海洋熱波のチェーンでは、よく知られる論文の 54 % という数値が、別の期間を対象とした別の分析を示すものであり、検証されていないことが記録されています。
constellation_raw(uri, …)
グラフまたは上流データの問題をデバッグするための、投影前のレスポンスです。サイズが大きいため、constellation の使用を推奨します。
template_fields(step, live=True) · vocabulary(name, live=True) · list_schemas()
ナノパブテンプレートはチェーンステップのスキーマそのものです。そのため、「フィールド名を決して創作しない」「主張タイプを決して創作しない」という、エージェントが覚えておかなければならないルールを、実在する値だけを返す検索機能に置き換えられます。
template_fields は、実際のフィールド ID、プロンプト、必須/繰り返し可能のフラグ、および regex/prefix/datatype の制約を返します。これらの制約が設定されている場所は、実際には Quote テンプレートの文字数上限であり、内容が古くなっていく手書きのドキュメントではありません。step には、05_outcome、05、または outcome を指定できます。
vocabulary は、実際の選択肢制限フィールドから取得した、制御語彙で許可されている値を返します。
| 名前 | 取得元 | 用語数 |
|---|---|---|
claim_type | 03_claim.forrtType | 7 |
study_type | 04_study.type | 3 — Reproduction と Replication の区別 |
validation_status | 05_outcome.validationStatus | 5 |
confidence_level | 05_outcome.confidenceLevel | 5 |
cito_relation | 06_citation.cites | 43。別の値リストナノパブ経由 |
question_type | 01_pico.type | 5 |
どちらもデフォルトでライブデータを取得し、ネットワークを利用できない場合は同梱スナップショットにフォールバックします。どちらを使用したかを必ず報告し、上流のテンプレートが置き換えられている場合は driftedFromSnapshot を設定します。結果にドリフトがある場合はライブの値が優先され、このパッケージを再ベンダリングする必要があることを意味します。これは、気づかないうちに徐々に乖離するのではなく、明示的に報告され、レビュー可能なイベントです。
cito_relation は、オフラインでは解決できない唯一の語彙です。別の値リストナノパブに含まれています。オフライン時には空のリストではなく、警告とともに source: "unavailable-offline" を返します。空のリストでは「有効な値がない」と解釈されるためです。
verify_chain(published_path, repo_url="")
チェーンを告知する前の最終チェックです。nanopubs/PUBLISHED.md
の台帳を指定します。green が true になるのは、失敗がなかった場合のみです。読み取り専用のため、編集、撤回、置き換えは行いません。
| チェック | 意味 |
|---|---|
| ledger | 必須の各ステップ(01–06)に URI がある |
| reachable | 各 URI が実際に公開されている |
| repository | Outcome のアーカイブ版 DOI を解決できる |
| cited-doi | チェーンが引用する各 DOI を解決できる |
| verdict-relation | CiTO の関係が Outcome の判定と一致している |
| cito-citing-work | 台帳の CiTO が台帳の Outcome から引用している |
| neighbours | ウォークで到達した他のチェーン。コンテキストのみで、判定対象外 |
特に見逃したくないのは最後のチェックです。Validated は confirms、PartiallySupported は qualifies、Contradicted は disputes を意味します。不一致は、Outcome と Citation の間で、再現実験で実際に判明した内容の解釈が食い違っていることを意味します。反証した論文に対して confirms を引用するチェーンは、チェーンがないよりも悪い状態です。
判定対象となるのは、台帳自体の Outcome と CiTO のみです。 公開済みの研究成果はネットワークを形成します。同じ論文を引用するチェーンは同じウォークで見つかり、1 つの CiTO が複数の研究成果を引用することもあります(論文を confirms し、手法を usesMethodIn で、データを citesAsDataSource で引用するなど)。そのため、関係→対象のペアは台帳のステップ 06 の TriG から読み取り、判定は Quote(ステップ 01)が引用する論文に対する関係と照合します。他のチェーンは neighbours として列挙されます。チェックを実行できない場合は、スキップせずに warn でその旨を示します。
コンステレーションだけではチェーンを検証できないため、このツールでは検証を試みません。実際の 2 つのチェーンでは、ウォークが上流のアンカーに届く前に停止します。そのため、列挙されないものはすべて、w3id.org/np/ のベアリゾルバーから TriG を取得してチェックします。/sciencelive/np/ 形式では HTML ビューアーが配信されます。これが 200 を返すと、ナノパブを配信していなくても、ステータスのみのチェックでは合格してしまいます。「ウォークでは列挙されなかったが、TriG は解決できる」と表示された行は警告ではなく、合格です。
Outcome のリポジトリには、GitHub URL ではなく Zenodo のバージョン DOI が指定される想定です。バージョン DOI は Outcome の計算元となったアーカイブ状態を固定しますが、github.com/ORG/REPO は更新されていく可能性があるためです。どちらも受け付けます。DOI は解決できるかを確認し、URL は repo_url と照合します。
公開済みの両方のチェーンは green で検証に合格します。これは marine-heatwave の台帳に記録された手動検証結果と一致しています。
validate_chain_draft(path)
nanopubs/chain-draft.json――実際に公開される成果物――をチェックしてから、Science Live チェーンウィザードに渡します。Phase 5b の最後に、pixi run build-chain-draft の実行後、ファイルをプッシュしてウィザードの URL を開く前に実行します。
Markdown のドラフトは執筆形式です。build_chain_draft.py が、これらに CITATION.cff とテンプレートを組み合わせてこのファイルを生成します。ウィザードはこのファイルをもとに各ステップの入力欄を事前入力し、人間が確認して署名します。validate_draft は入力をチェックし、こちらは成果物をチェックします。
ファイルを読むだけでは見つけられない問題も検出します。
- 古い
template_uri――JSON からは分かりませんが、ウィザードで古いフォームが事前入力されます。 - テンプレートのフィールドでも既知のプラットフォームのフォームフィールドでもない
prefillキー。ウィザードはこれを通知なく破棄します。 - 複雑なフィールドの形式が誤っている場合――
06_citation.st02は少なくとも 1 件のエントリーを含む[{cites, cited}]でなければならず、04_study.disciplineSelectionは配列ではなく単一のオブジェクトです(この契約における唯一の非対称な点です)。 - 事前入力も引き継ぎもされていない必須フィールド。
- テンプレート独自の上限を超える値、無効な語彙項目、不正な日付、解決されていない
{{TOKEN}}、解決できない DOI。 - チェーンを逆方向にたどる
carry_forwardエッジ。
ウィザードが自動入力するフィールドは、不足として報告されず、チェック対象外となります。02_aida には project、03_claim には aida、04_study には claim がありません。
このプロジェクトの実際のチェーンドラフトはどちらも問題なく検証され、片方に意図的に加えた 13 個の変更も、それぞれすべて検出されます。
validate_draft(path) · validate_drafts(directory)
docs/forrt-form-fields.md に記載された事前チェックリストを実際に実行します。1 回の呼び出しで、ナノパブのドラフトを最初から最後までチェックします。フィールド ID を最新のテンプレートと照合し、選択肢の値をテンプレートの列挙値と照合し、長さの上限を正規表現と照合し、DOI をレジストリと照合し、QID を Wikidata と照合します。エラーがなければ、publishable は true になります。
これが、他のツールが存在する目的をまとめた処理です。個別のツールは「この値は実在するか?」に答え、組み合わせると「このドラフトは公開可能か? 不可能なら、どこに問題があるのか?」に答えます。
プレースホルダーの規則は 3 種類あり、問題になるのは 1 種類だけです。 これを正しく扱わなかったため、実際のドラフトに対してチェッカーが役に立たなくなったことがありました。そのため、それぞれを明示的に処理します。
| ドラフト内の表記 | 意味 | 重大度 |
|---|---|---|
«URI of step 05 …» | 参照先へのバックリファレンス。チェーンウィザードが公開済みのステップから入力します | 情報 |
{{ZENODO_VERSION_DOI}} | リリース時のトークン。リリースワークフローで置き換えます | 警告 |
| 値の代わりに使われているその他のもの | 実際に未入力 | エラー |
必須フィールドがほぼすべて空のドラフトは、フィールドごとのエラーが大量に並ぶのではなく、未入力のスケルトンとして「まだドラフトが作成されていません」と 1 回だけ報告されます。
検出できないもの。 ドラフト内の値が `` マーカーの背後ではなく、文章や Markdown の表に記載されている場合、不足としてではなく coverage 警告として報告されます。CiTO ステップの引用リストが該当する既知のケースです。確認した両方のリポジトリで、cites と cited は表に記載されています。
公開済みの実際のチェーン 2 件(marine-heatwave と Sado estuary)で検証済みです。どちらも公開済みの 6 ステップすべてが合格し、残るフラグは未公開のステップ 07 と上記のリリーストークンのみです。
resolve_doi(doi)
この DOI は解決できるか、また何に解決されるかを確認します。resolves: false は、登録されていないことを意味します。形式が正しい DOI でも実在するとは限りません。レジストリに問い合わせるまでは、捏造した DOI と本物の DOI を見分けられません。登録されているタイトル、著者、年、掲載誌を返すため、単に実在する論文ではなく、意図した論文かどうかを確認できます。doi: 形式のほか、裸の DOI と URL 形式も受け付けます。5xx は無効な DOI ではなく、一時的なエラーとして報告されます。
wikidata_lookup(query, expected_type="", limit=5)
用語に該当する、実在するWikidata候補と、実際のP31/P279型を返します。
expected_type にQIDを指定すると、各候補に typeMatches が付きます。
このプロジェクトで公開されているチェーンに含まれる10個のWikidata用語(
build_chain_draft.py が解決し、署名したQID)で検証済みです。10個すべてについて、
公開済みのQIDが1位で返されます(marine heatwave、sea surface temperature、climate change、
time series analysis、chlorophyll a、remote sensing、estuary、Sentinel-2、water
quality、atmospheric correction)。
意図的に選択は行いません。曖昧なラベルの正しい意味を選ぶのは、判断を要する作業です。Q16521(分類群)を指定して Bombus を検索すると、
昆虫の属は一致候補として、同名のアルバムは不一致候補として返されます。これは、QIDがナノパブに署名される前に検出すべき失敗をまさに捉えるものです。候補には注釈を付けますが、絞り込みは行いません。惜しい候補こそ、有益な結果であることがよくあります。候補が0件の場合は、フィールドを空のままにしてください。記憶に頼ってQIDを補完してはいけません。
cito_to_wikidata(cito_uris=None, published_path="")
公開済みの型付き引用(「この再現研究は、その論文を確認する」)をWikidataとScholiaで参照できるようにします。WikidataではすでにCiTOがモデル化されています。「cites work」(P2860)に「has goal」(P3712)修飾子を付け、48種類の引用意図項目のいずれかを設定します。各項目には、対応するCiTO URIとの完全一致(P2888)があります。そのため、対応関係は実行時にWikidataから読み取られ、ここにコピーされることはありません(コピーすると、気付かないうちに古くなるためです。Wikidataに接続できない場合は、ツールがその旨を伝えます)。記述には「nanopublication identifier」(P12545)を https://w3id.org/np/<id> 形式で引用します。この形式はScholiaによって、ナノパブリケーションで定義された注釈として集計されます。
Wikidataは一切編集しません。 QuickStatementsのバッチと、論文ごとのレポートを返します。担当者が内容を確認し、自分のアカウントを使って https://quickstatements.toolforge.org でバッチを送信します。コマンドとしても利用できます。
forrt-wikidata-cito --published nanopubs/PUBLISHED.md --out wikidata
保証されること:
- DOIで項目(著者はORCID)を検索し、不足している場合にのみ作成します。
- 論文ごとに項目を1つ作成します。Zenodoのバージョンは概念DOIの下にまとめられるため、1つの登録物の2つのバージョンが、2つの再現研究として扱われることはありません。
- 冪等です。Wikidataにすでにある引用はスキップされます。同じバッチで作成された論文への引用は
pendingとして記載され、次回の実行時に追加されます。 - 新しい項目に含まれるすべての事実(型、タイトル、DOI、日付、著者)には、情報の取得元であるZenodoレコードが出典として付けられます。Wikidataは二次ナレッジベースであり、引用自体はそのナノパブリケーションを引用します。
- 説明文は短い文章(「による再現または追試研究()」)にし、識別子は本来記載すべきステートメントに記載します。
項目はZenodoレコードのタイトルから作成されます。送信前に、Zenodo上でリポジトリのスラッグが含まれたタイトルを修正してください。
validate_rocrate(path, profile="ro-crate-1.2", level="REQUIRED", metadata_only=False, offline=False)
レプリケーションを公開または ROHub に登録する前に、その ro-crate-metadata.json を、テンプレートの CI で実行されるものと同じバリデーター(rocrate-validator)で検査します。path には、クレートのディレクトリまたはメタデータファイルを指定します。
passed/issues—profileに対する仕様チェックをlevel(REQUIRED、RECOMMENDED、OPTIONAL)で実行します。各問題には、チェック名、メッセージ、該当するエンティティが示されます。metadata_only=Trueにすると、クレートのデータがチェックアウトされていない場合に、一覧に記載されたファイルの存在チェックを省略します。初回実行時に RO-Crate の JSON-LD コンテキストを取得してキャッシュします。offline=Trueにすると、そのキャッシュを使用します。fdo_checks/fdo_ready— クレートが FAIR デジタルオブジェクトとして機能するために仕様を超えて必要とするものを示します。永続識別子、ライセンス、mainEntityとしてのワークフロー、conformsToに指定されたコミュニティの FAIR Implementation Profile、subjectOfに指定された FORRT チェーン、さらに構成要素にro-crate-metadata.jsonを含めないこと(ROHub ではその名前が予約されています)が必要です。これは参考情報であり、passedの値は変わりません。各チェックに失敗した場合は、修正方法が示されます。
クレートはテンプレートの scripts/build_rocrate.py で生成します。ソース(CITATION.cff、nanopubs/PUBLISHED.md、rocrate.json)を修正して再ビルドしてください。合格させるためにファイルを直接編集しないでください。
このツールが対応する上流の癖
API の仕様を読むのではなく、実際のデータを調べて発見したものです。それぞれ、実際に記録されたペイロード(互いに無関係な研究の2つのコンステレーション)を使ったテストで固定されています。
- Cloudflare は urllib のデフォルトの User-Agent を拒否します。 API は Cloudflare Workers 上で動作しており、そのボット保護機能は
Python-urllib/3.xに HTTP 403 を返します。同じ URI とキーでも、通常のエージェントなら 200 が返ります。このクライアントは、すべてのリクエストに明示的なUser-Agentを設定します。独自のクライアントでも同様に設定してください。密閉型のテストではこの問題を検出できません。 paperDoiが誤った論文を示すことがあります。 全体の探索における頻度から選ばれるため、隣接する研究の Quote nanopub が、そのチェーン自身の引用を上回ることがあります。marine-heatwave チェーンでは、チェーンの CiTO が実際に引用している Oliver らの2018年の論文ではなく、LifeWatch ERIC の論文(無関係な引用4件)を報告します。さらに、無関係な Sado-estuary のエントリーポイントからも同じ誤った論文が示されるため、これは1つの誤ったレコードではなく、システム全体に関わる問題です。citedPaperは CiTO から論文を特定し、両者が異なる場合はdisagreesWithReportedを設定します。- 探索は途中で止まり、見つからないことは未公開を意味しません。 実在する2つのチェーンでは、
[Claim, Study, Outcome]と[Study, Outcome, CiTO]が列挙されていましたが、それらのリポジトリのPUBLISHED.mdに記載された Quote、AIDA、Claim nanopub は公開済みであり、単に到達できないだけでした。stepsNotEnumeratedはこの欠落を報告します。コンステレーションだけではチェーン全体を検証できません。該当する URI の TriG を直接取得してください。 - 現在の quote テンプレートを使う nanopub では、
quote.quotedTextが空で返されます。 テキストはlabelと、タグのない2つの抜粋(引用文と注釈者のコメント)に残っていますが、並び順は保証されません。位置を決めつけず、抜粋とラベルの語幹を照合し、復元できたことをtext_sourceで報告します。 - 最上位の CiTO は、
chains[].steps[]からトップレベルに移されています。 /sciencelive/np/形式の URI は HTML ビューアーを返し、200 を応答するため、実際には nanopub が提供されていなくても、ステータスだけを確認する到達性チェックに合格してしまいます。 URI をベアなw3id.org/np/リゾルバー形式に正規化し、本文が RDF であることを確認します。
実在するすべてのアーティファクトを対象に確認する
テストスイートは外部に依存しないよう設計されており、記録済みデータに基づいて動作を固定しています。これによりリグレッションは防げますが、前提の誤りは発見できません。このサーバーで発生した重大なバグはすべて前提の誤りであり、いずれもツールが未確認の実データを処理したときに初めて明らかになりました。そのため、「網羅的にテストできているか」はここでは主観的な判断ではなく、分母が明確な計算です。
python scripts/check_corpus.py /path/to/your/study/repos
nanopubs/ ディレクトリを持つすべてのリポジトリを検出し、各アーティファクトに対して該当するツールを実行し、見つかった項目のうち何件が合格したかを出力します。検出結果は自動的に失敗とはなりません。必須フィールドが空であることは、下書きの実態を正しく示している場合があります。終了コードが 0 以外になるのは、クラッシュまたは解析の失敗が発生したときです。これは、ツールが実在するアーティファクトをまったく読み取れなかったことを意味するためです。
分母の正確さは、ディスク上にあるデータに依存します。そのルート配下にないチェーンは対象外であり、テストがすべて成功しても、その点は変わりません。
開発
pip install -e '.[dev]'
pytest
287 件すべてのテストは外部に依存せず、ネットワーク、API キー、稼働中のサービスを必要としません。constellation のフィクスチャには実際に記録された /np/constellation の応答を使用し、引用のテストでは抽出時のアーティファクトを意図的に再現する最小限の PDF をプロセス内で生成します。また、テンプレート、DOI、Wikidata のテストでは、記録済みのペイロードを使って HTTP 通信をスタブ化しています。上流サービスが停止しても、テストスイートは引き続き成功します。
src/forrt_research_mcp/data/ 配下に同梱されているテンプレートのスナップショットは、template_spec.py と同様に ScienceLiveHub/forrt-replication-template からベンダー化されています。template_fields が driftedFromSnapshot を報告した場合は、再度ベンダー化してください。
ライセンス
MIT — LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。