VSCodeをMCPサーバーとして使ってコードを生成してみよう

はじめに
前回の記事では、Model Context Protocol (MCP)の基本的な環境構築について説明しました。今回は、その続きとしてVSCode自体をMCPサーバーとして動作させ、実際にコードを生成する方法について解説していきます。 癖はありますし、指示があいまいだと書いたコードをすべて破壊して好き勝手なコードを書き始めて困るものの 実際にVSCode上でコードを高速で書き換えて動作するものを叩き出してくる様を見せられると活用していく必要がありそうだと感じます。
適用範囲
- VSCodeユーザー
- GitHub Copilotを利用している方
- AIを活用したコード生成に興味がある方
- Pythonでの開発を行っている方
準備
まず、VSCodeをMCPサーバーとして動作させるために必要な設定を行います。前回の環境に追加で以下の設定を行います:
{
"mcp": {
"inputs": [],
"servers": {
"vscode": {
"command": "code",
"args": ["--ms-enable-electron-run-as-node", "--stdio"],
"env": {}
},
"mcp-server-translate": {
"command": "python",
"args": [
"-m",
"mcp_server_translate",
"--source-lang=zh-CN",
"--target-lang=en",
"--source-lang=zh-TW",
"--target-lang=en"
],
{}mcp@latest"]
},
"mcp-installer": {
"command": "npx",
"args": [
"@anaisbetts/mcp-installer"
]
},
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
#
対話形式で直接コードを書いてもらいました。
実際に書いているコードを上から書き換えてくれ、差分を反映させるか選択してくれます。
## 結果
吐き出したコードを実行します。
python pygames.py

[Xに動画投稿しておきました。](https://x.com/i/status/1913993846465438036)
## まとめ
Agentモードでのコード生成は非常に効率的でモックアップとしては十分に使えるものを叩き出してくれました。
それこそアルゴリズム系の実装など方針さえ立ててしまえばある程度のものを完成させてくれそうな雰囲気は感じます。
ひとまずチュートリアルとしては十分な成果を得られました。
なんかうごくものが出来上がってしまいました。
### ソースコード
マジで何も手をほとんど加えていないのですがテトリスのコードを書いてくれたので張っておきます。
これ丸ごとどこから持ってきたコードなんじゃないかとすら思ってしまうぐらいちゃんと動いてるのが不気味ですね。
import pygame import random
Initialize pygame
pygame.init()
Screen dimensions
SCREEN_WIDTH = 300 SCREEN_HEIGHT = 600 BLOCK_SIZE = 30
Colors
BLACK = (0, 0, 0) WHITE = (255, 255, 255) GRAY = (128, 128, 128) COLORS = [ (0, 255, 255), # Cyan (255, 255, 0), # Yellow (255, 165, 0), # Orange (0, 0, 255), # Blue (128, 0, 128), # Purple (0, 255, 0), # Green (255, 0, 0) # Red ]
Tetromino shapes
SHAPES = [ [[1, 1, 1, 1]], # I [[1, 1], [1, 1]], # O [[0, 1, 0], [1, 1, 1]], # T [[1, 0, 0], [1, 1, 1]], # L [[0, 0, 1], [1, 1, 1]], # J [[0, 1, 1], [1, 1, 0]], # S [[1, 1, 0], [0, 1, 1]] # Z ]
class Tetromino: def init(self, x, y, shape): self.x = x self.y = y self.shape = shape self.color = COLORS[SHAPES.index(shape)] self.rotation = 0
def get_shape(self):
return self.shape
def rotate(self):
# Convert shape to list if it's not already
current_shape = self.shape
# 時計回りに90度回転
rows = len(current_shape)
cols = len(current_shape[0])
rotated = [[0 for _ in range(rows)] for _ in range(cols)]
for r in range(rows):
for c in range(cols):
rotated[c][rows-1-r] = current_shape[r][c]
self.shape = rotated
def valid_move(piece, grid, x_adjust=0, y_adjust=0): for y, row in enumerate(piece.get_shape()): for x, cell in enumerate(row): if cell: pos_x = piece.x + x + x_adjust pos_y = piece.y + y + y_adjust
if not (0 <= pos_x < 10 and pos_y < 20):
return False
if pos_y >= 0 and grid[pos_y][pos_x] != BLACK:
return False
return True
def create_grid(locked_positions={}): grid = [[BLACK for _ in range(10)] for _ in range(20)] for (x, y), color in locked_positions.items(): if y < 20: grid[y][x] = color return grid
def draw_grid(surface, grid): for y in range(len(grid)): for x in range(len(grid[y])): pygame.draw.rect(surface, grid[y][x], (x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 0)
# Draw grid lines
for x in range(11):
pygame.draw.line(surface, GRAY, (x * BLOCK_SIZE, 0), (x * BLOCK_SIZE, SCREEN_HEIGHT))
for y in range(21):
pygame.draw.line(surface, GRAY, (0, y * BLOCK_SIZE), (SCREEN_WIDTH, y * BLOCK_SIZE))
def draw_piece(surface, piece): shape = piece.get_shape() for y, row in enumerate(shape): for x, cell in enumerate(row): if cell: pos_x = (piece.x + x) * BLOCK_SIZE pos_y = (piece.y + y) * BLOCK_SIZE pygame.draw.rect(surface, piece.color, (pos_x, pos_y, BLOCK_SIZE, BLOCK_SIZE))
def clear_rows(grid, locked): inc = 0 for i in range(len(grid)-1, -1, -1): row = grid[i] if BLACK not in row: inc += 1 for j in range(i, 0, -1): for x in range(len(grid[0])): grid[j][x] = grid[j-1][x] for x in range(len(grid[0])): grid[0][x] = BLACK
# Update locked positions
new_locked = {}
for (x, y), color in locked.items():
if y < i:
new_locked[(x, y + 1)] = color
elif y > i:
new_locked[(x, y)] = color
locked = new_locked
return inc
def draw_window(surface, grid, piece): surface.fill(BLACK) draw_grid(surface, grid) if piece: draw_piece(surface, piece) pygame.display.update()
def main(): screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption(“Tetris”) clock = pygame.time.Clock()
locked_positions = {}
grid = create_grid(locked_positions)
change_piece = False
current_piece = Tetromino(5, 0, random.choice(SHAPES))
fall_time = 0
fall_speed = 0.5
run = True
while run:
fall_time += clock.get_rawtime()
clock.tick()
if fall_time/1000 >= fall_speed:
fall_time = 0
if valid_move(current_piece, grid, 0, 1):
current_piece.y += 1
else:
# Lock the piece and create new piece
for y, row in enumerate(current_piece.get_shape()):
for x, cell in enumerate(row):
if cell:
pos = (current_piece.x + x, current_piece.y + y)
locked_positions[pos] = current_piece.color
current_piece = Tetromino(5, 0, random.choice(SHAPES))
if not valid_move(current_piece, grid):
run = False
break
grid = create_grid(locked_positions)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT and valid_move(current_piece, grid, -1, 0):
current_piece.x -= 1
if event.key == pygame.K_RIGHT and valid_move(current_piece, grid, 1, 0):
current_piece.x += 1
if event.key == pygame.K_DOWN and valid_move(current_piece, grid, 0, 1):
current_piece.y += 1
if event.key == pygame.K_UP:
# Store the current rotation
original_shape = current_piece.shape[:]
current_piece.rotate()
if not valid_move(current_piece, grid):
# If rotation is not valid, revert back
current_piece.shape = original_shape
clear_rows(grid, locked_positions)
draw_window(screen, grid, current_piece)
pygame.quit()
if name == “main”: main()