Skip to main content
Glama
hotaka052

linear-mcp-wrapper

by hotaka052

linear-mcp-wrapper

Linear の MCP サーバーへの接続を肩代わりする薄いサーバー。

呼ぶ側(tsuzuri の runner)はこのサービスの URL だけを知っていればよく、Linear の資格情報を一切持たない、という形にするための repo。

before:  runner ──MCP──> mcp.linear.app        (runner が client_secret を持つ)
after:   runner ──MCP──> このサービス ──MCP──> mcp.linear.app

いまの状態: 置いただけ

まだサーバーとして動かない。 tsuzuri から認証まわりのコードを退避させただけで、 プロキシ本体(src/main.py)はまだ無い。tsuzuri 側もまだ何も消していないので、 そちらは今までどおり直接 Linear を見ている。

ファイル

出どころ

src/auth.py

tsuzuri の runner/src/linear.pyそのままコピー(1 文字も変えていない)

src/config.py

tsuzuri の runner/src/config.py の Linear の部分だけ

src/logs.py

tsuzuri の runner/src/logs.py から emit だけ

env/master.yaml

tsuzuri の runner/env/master.yaml の Linear の部分だけ

src/auth.py の docstring で、もう合っていない記述

そのままコピーした副作用。中身の理屈は全部生きているが、参照先の名前だけが古い。

  • 「入口は intake.py、出口は writeback.py」— どちらも tsuzuri 側に残っている

  • 「MCP サーバーへの接続ヘッダに使う(mcp_tools.build)。唯一の呼び出し元。」— ここを呼ぶのは、これから書くプロキシ本体になる

Related MCP server: Uno MCP Stdio

これから書くもの

  1. プロキシ本体(src/main.py)。 ここが本番。素通しの HTTP プロキシでは済まない:

    • POST のレスポンスが JSON のことも SSE のこともある (クライアントは Accept: application/json, text/event-stream で来る)

    • 別に GET で長寿命の SSE を張る(サーバー→クライアント方向。切れたら再接続してくる)

    • mcp-session-idmcp-protocol-version を両方向で素通しする必要がある。 初回レスポンスで発行されたセッション ID を、クライアントは以降の全リクエストに付けてくる

    • セッション終了は DELETE

    • バッファしないこと。 await response.json() で受けると SSE がそこで固まる。 httpx.AsyncClient.stream() + Starlette の StreamingResponse で流す

  2. 呼ぶ側の認証。 クライアントから来る Authorization は Cloud Run の OIDC ID token にして、ここで上流用のトークン(auth.py)に差し替える。 Cloud Run は --no-allow-unauthenticated で立てる

  3. ツールの絞り込み(あとで)。 tools/list のレスポンスから許可リストにない ツールを落とす。いまは tsuzuri 側の INTAKE_TOOL_FILTER / WRITEBACK_TOOL_FILTER がやっているので、動いてから移す

3 をやるときに知っておくこと

上流のツールを全部そのまま渡すと、呼ぶ側のモデル呼び出しごと落ちる。 Linear の MCP は 53 本公開していて、Vertex の function declaration が受け付けない スキーマが混ざっていると 400 INVALID_ARGUMENT になる(tsuzuri で実測)。 いま tsuzuri が使っているのは実質この 4 本だけ:

  • 入口: get_issue, list_comments

  • 出口: save_comment, save_issue

入口と出口でリストを分けていること自体が権限の境界になっている(一本にまとめると、 依頼を読むだけのエージェントが delete_comment を持つ)。ここに移すときも分けたまま 持ってくること。エンドポイントを分けるのが素直。

開発

uv sync

ローカルでは LINEAR_API_KEY(個人 API キー)を入れれば OAuth を通らずに済む。 Cloud Run では LINEAR_CLIENT_ID + LINEAR_CLIENT_SECRET(Secret Manager)を使う。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Local stdio proxy for Uno MCP Gateway that enables MCP clients without OAuth support to securely connect to authenticated remote servers.
    20 PyPI
    1
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Bridge that lets stdio-only MCP clients connect to remote MCP servers with OAuth and other auth support, enabling local clients to use remote, authorized MCP servers.
    60 npm
    54
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables multiple MCP clients to securely access various third-party MCP backends through a single HTTP gateway, with modern MCP handshake compatibility and session lifecycle management.
    9 npm
    MIT