Model Context Protocol: A year later

Tomasz Godzik

VirtusLab

What do I do?

Maintainer of multiple Scala tools including Metals, Bloop, Scalameta, Munit, Mdoc and parts of the Scala 3 compiler.

 

Maintainer of multiple Scala tools including Metals, Bloop, Scalameta, Munit, Mdoc and parts of the Scala 3 compiler.

 

Release officer for Scala LTS versions

 

 

Maintainer of multiple Scala tools including Metals, Bloop, Scalameta, Munit, Mdoc and parts of the Scala 3 compiler.

 

Release officer for Scala LTS versions

 

Part of the Scala Core team as coordinator and VirtusLab representative

 

 

Maintainer of multiple Scala tools including Metals, Bloop, Scalameta, Munit, Mdoc and parts of the Scala 3 compiler.

 

Release officer for Scala LTS versions

 

Part of the Scala Core team as coordinator and VirtusLab representative

 

Part of the moderation team

Model Context Protocol

what is it?

01

02

03

04

MCP & Scala

Executable MCP and skills

Questions

Model Context Protocol

 

Model Context Protocol is very similar to Language Server Protocol, but instead of people it's for agents.

Host with MCP Client

MCP protocol

MCP protocol

MCP protocol

MCP Server 1

MCP Server 2

MCP Server 2

Local Data Source 1

Local Data Source 2

Web API

Why do we even need Model Context Protocol?

AI can sometimes go bonkers

Hallucinations are a problem, we want to reduce the amount of non-determinism in your tools

MCP provides information to your AI coding agent that it can use to verify and enrich its responses

 

But it's also a way to better query your information

Core MCP Concepts

MCP uses Json RPC, so each possible request and response is represented by json schema

Agents can ask the server for static content (resources) that might be useful for the current context

 

resources/list - list all available resource 
resources/read - read specific resource

Resources

{
  uri: string;           // Unique identifier for the resource
  name: string;          // Human-readable name
  description?: string;  // Optional description
  mimeType?: string;     // Optional MIME type
}

Resources

Example

{
  uri: "file:///logs/app.log",
  name: "Application Logs",
  mimeType: "text/plain"
}

 Agents interact with external systems, perform computations, and take actions in the real world.

 

tools/list - list all the tools available on the server

tools/call - invoke the tool

Tools

{
  name: string;          // Unique identifier for the tool
  description?: string;  // Human-readable description
  inputSchema: {         // JSON Schema for the tool's parameters
    type: "object",
    properties: { ... }  // Tool-specific parameters
  },
  annotations?: {}       // Optional hints about tool behavior
}

Tools

Example

{
  "name" : "compile-file",
  "description": "Compile a chosen Scala file",
  "schema" : {
    "type": "object",
    "properties": {
      "fileInFocus": {
         "type": "string",
         "description": "The file to compile..."
      }
    }
  }
}

- reusable prompt templates and workflows

- standardize and share common LLM interactions

- prompts/list and prompts/get requests

Prompts

{
  name: string;              // Unique identifier for the prompt
  description?: string;      // Human-readable description
  arguments?: [              // Optional list of arguments
    {
      name: string;          // Argument identifier
      description?: string;  // Argument description
      required?: boolean;    // Whether argument is required
    }
  ]
}

Prompts

Example

{
  name: "explain-code",
  description: "Explain how code works",
  arguments: [
      {
        name: "code",
        description: "Code to explain",
        required: true
      },
      {
        name: "language",
        description: "Programming language",
        required: false
      }
    ]
}

How it's used

  • You first need to add mcp servers to your config (there is a lot of them!)
  • They can be enabled and disabled as needed.
  • Agents will ask before using each tool, take care not to allow all on tools contacting outside world (YOLO mode is dangerous)

MCP with Scala

Metals

Metals is a language server protocol server.

Metals is also a model context protocol server.

Why do it in Metals?

Metals has the exact data to serve both purposes and makes it easier for people who already use it.

 

And soon there will be default standalone MCP server for use outside Metals (Intellij!)

You can also build your own servers with Chimp, your own agents with sttp-ai

compile-full: Compile the entire Scala project.
compile-module: Compile a single module
compile-file: Compile current module and show errors from the current file

 

Most used by the agents, quick feedback loop and perfect for YOLO mode.

Compile Tools

test: Run a Scala test suite or case

Test tools

​Often used, but my require additional direction for the agent

glob-search: Search for symbols using a glob pattern.
typed-glob-search: Search for symbols by type.
inspect: Inspect a symbol for members, signatures...
get-docs: Retrieve documentation for a symbol 
get-usages: Find usages of a symbol.

 

Search Tools

Rarely used, requires prompting the agent. A lot of the times replaced by grep even if the data is outside the workspace.

import-build: Trigger a build import in the IDE.
format-file: Format given file, results applied directly
find-dep: API to allow coursier complete-dep

 

Utility Tools

Custom, mostly needs to be prompted or added in agent context

generate-scalafix-rule: ask metals to compile and run given generate scalafix rule

 

run-scalafix-rule: run existing or previously generated rule

 

list-scalafix-rules: list all existing and previously generated rules

Scalafix Tools

Experimental, works only when user knows what they want.

What's your tool idea!?

 

Might be worth implementing in Metals if general enough

More Tools

It requires a lot of work to make a good and useful tool.

MCP Tools

 

And it might not even be used!

MCP Tools

But it's still useful to have that in your arsenal

 

  • Keep note of what model is used whether it uses some tools.
  • Add agentic files to force agent to use the tools at specific times.
  • Don't add too many tools! Context is king.

 

 

MCP Tools

Problems with MCP

  • The more tools you have the more context is taken up
  • Model efficiency might go down and it might start hallucinating more
  • Data returned from the tools might go through the model adding to the context

Problems with MCP

  • In some cases people had context filled up to 20-30 % only by using MCP tools, system prompts etc. before even running the main prompt
  • It's often recommended to keep the context down at 50 % -> this depends on the model

Problems with MCP

  • In some cases good CLI might be enough and better than creating additional MCP tools
  • For example scala-cli might not need to be run through Metals, sbt might be a good candidate

Is there another option?

Executable tools and skills

Code execution with MCP

  • Instead of having all tools listed we can have a hierarchical list of toolsets and then tools within them 
servers
├── metals
│   ├── globSearch.scala
│   ├── getDocs.scala
│   ├── ... (other tools)
│   ├── clientUtils.scala
├── github
│   ├── issue.scala
│   ├── ... (other tools)
└── ... (other servers)
  • Each toolset and tool can be a separate mini library
// ./servers/metals/globSearch.scala
package metals.mcp

/* Potential pseudocode of a library with Ox */
def globSearch(
    fullyQualifiedName: String, 
    target: Option[String]): String =
  client.callTool("glob-search", fullyQualifiedName, target)

Code execution with MCP

  • The agent queries each toolset it needs and creates executable code

Code execution with MCP

// ./skills/getDocsFor.scala
import metals.mcp.*

@main
def main(nameToLookFor: String) =
  val allMatching = globSearch(fullyQualifiedName, None)
  val fqcns = allMatching.split("\n")
  val result = fqcns.map{
    fullName => getDocs(fullName)
  }.mkString("\n")
  println(result)
}
  • To improve discoverability we can have an additional tool for searching within the existing tools
  • Metals or Intellij could set up the basic servers as tools
  • We need a client for MCP, that could also help with other MCP servers
  • The code could then be generated from the tool definitions

Code execution with MCP

Existing code executions

  • We already have some tools that work in this manner
  • Scalafix rule generation that is available in Metals MCP
  • Results are applied directly, they don't go through the model
  • LLMs only generate code that works on your codebase

Benefits

  • If you're working on confidential data, this can be handled in the script and not fed to the LLM
  • And that data will also not make the context any bigger

Benefits

  • Much smaller context than normal MCP since models are efficient at navigating file trees, they only pick what they need
  • You can do much more even with short scripts instead of relying on model to do the right thing

Security

  • You still need to check the code and make sure it does what you want it to do 
  • You cannot YOLO mode it for sure
  • Come to ScalarConf if you want to hear more about this topic, there is something brewing at EPFL

This is all still a lot of work

Skills

  • Each such generated script can be saved to your personal library of "skills", which is another related agentic topic
  • Their main goals:
    • Specialize: Tailor capabilities for domain-specific tasks
    • Reduce repetition: Create once, use automatically
    • Compose capabilities: Combine Skills to build complex workflows

Skills

You can think of it as your personal library of scripts that will also be available to the agents. And obviously you will be able to run them as well.

 

You can create skills based on session with and agent, so that next time you will get instant results.

Skills

  • Similar and based on the lesson from MCP we want to avoid overloading the context
  • There are three types of Skill content, three levels of loading
  • Only first level is loaded by default and is added at the start of SKILL.md file
---
name: get-docs-for-glob
description: Search for classes that satisfy this search parameters and...
---

Skills

  • Second level is actual inctructions further in the SKILL.md file
# Glob search

## Quick start

Run the script if you want to return users entire 
documentation based on specific glob 
(part of the name user is looking for) 

```bash
scala-cli search-script.scala
```

Skills

  • Third level is resources mentioned in the main SKILL.md file, they are loaded as needed.
glob-skill/
├── SKILL.md (main instructions)
├── REFERENCE.md (detailed API reference)
└── scripts/
    └── globSearch.scala (utility script)

Skills

---
name: your-skill-name
description: Brief description of what this Skill does and when to use it
---

# Your Skill Name

## Instructions
[Clear, step-by-step guidance for Claude to follow]

## Examples
[Concrete examples of using this Skill]

Skills, MCP and MCP tool execution all ties together

Skills, MCP and MCP tool execution all ties together

but

there is some work needed to make it for Scala for more complex usage

Usage

Not every tool will be able to use it.

 

Cursor generates a query that creates a new skill you might need.

 

Claude might also help, but you need to make sure the new file is created in .claude/skills

Thank You

Tomasz Godzik

Bluesky:      @tgodzik.bsky.social 

Mastodon:  fosstodon.org/@tgodzik

Discord:       tgodzik

 

tgodzik@virtuslab.com

Some links:

https://www.anthropic.com/engineering/code-execution-with-mcp

MCP a year later

By Tomek Godzik

MCP a year later

  • 7