aia 0.9.22 → 0.9.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.version +1 -1
- data/CHANGELOG.md +49 -0
- data/README.md +165 -0
- data/lib/aia/config/base.rb +59 -0
- data/lib/aia/config/defaults.rb +3 -0
- data/lib/aia/utility.rb +12 -1
- data/lib/extensions/openstruct_merge.rb +4 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 38ae30b2341fb1e96738601b0c7cac5459772217d005aa5e22f18ecde270e2e0
|
|
4
|
+
data.tar.gz: 34555fad44d99436b4171887c0804c88f88e6fdc572e8a2d05476f485b0b80c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 67182004edf9443ad3fc9190c1d57daa18c8f997d0425fa642e6f4c0c94d74490a1943ae1f79e7b18f55f65c0237a8fba31e765b750c374c8885926cbc08ca62
|
|
7
|
+
data.tar.gz: 3a86c4b7734a955180e7282a5462f7cda7ff83d1eac49c7106e63a69eaf9554a318ef2195ef61c4a61aec2340be6fdac8d19fd0d6a681f450e6c6c55b7c02940
|
data/.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.9.
|
|
1
|
+
0.9.23
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,55 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
## [Unreleased]
|
|
3
3
|
|
|
4
|
+
## [0.9.23] 2025-12-06
|
|
5
|
+
|
|
6
|
+
### New Features
|
|
7
|
+
- **MCP Server Configuration**: Added native support for defining MCP (Model Context Protocol) servers in the config file
|
|
8
|
+
- Configure MCP servers in `~/.aia/config.yml` under the `mcp_servers` key
|
|
9
|
+
- Supports `name`, `command`, `args`, `env`, and `timeout` options per server
|
|
10
|
+
- Automatic PATH resolution for commands (no absolute paths required)
|
|
11
|
+
- Configurable timeouts for slow-starting servers (default: 8000ms)
|
|
12
|
+
- Environment variable support for MCP server processes
|
|
13
|
+
|
|
14
|
+
### Improvements
|
|
15
|
+
- **Robot Display**: Added MCP server names to the robot ASCII art display
|
|
16
|
+
- Shows "MCP: server1, server2, ..." when MCP servers are configured
|
|
17
|
+
|
|
18
|
+
### Technical Changes
|
|
19
|
+
- Added `load_mcp_servers` method to `lib/aia/config/base.rb` for automatic MCP client registration
|
|
20
|
+
- Added `resolve_command_path` method for PATH-based command resolution
|
|
21
|
+
- Added `mcp_servers?` and `mcp_server_names` helper methods to `lib/aia/utility.rb`
|
|
22
|
+
- Fixed `OpenStruct.merge` to skip nil values, preventing config file values from being overwritten
|
|
23
|
+
- Added `mcp_servers: nil` default to prevent merge issues with empty arrays
|
|
24
|
+
|
|
25
|
+
### Configuration Example
|
|
26
|
+
```yaml
|
|
27
|
+
# ~/.aia/config.yml
|
|
28
|
+
:mcp_servers:
|
|
29
|
+
- name: "my-server"
|
|
30
|
+
command: "my_mcp_server.rb"
|
|
31
|
+
args: ["stdio"]
|
|
32
|
+
timeout: 30000
|
|
33
|
+
env:
|
|
34
|
+
MY_VAR: "value"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## [0.9.22] 2025-11-12
|
|
38
|
+
|
|
39
|
+
### Bug Fixes
|
|
40
|
+
- **TEST SUITE**: Fixed all Mocha test isolation issues causing stub contamination between tests
|
|
41
|
+
- Added proper teardown methods with `super` calls to 13 test files to ensure Mocha cleanup
|
|
42
|
+
- Fixed PromptHandlerTest missing teardown and config fields (erb, shell, roles_dir)
|
|
43
|
+
- Fixed ModelsDirectiveTest to use consistent stubbing approach instead of mixing real and stubbed config
|
|
44
|
+
- Fixed MultiModelIsolationTest to use stubs instead of direct instance variable manipulation
|
|
45
|
+
- Fixed AIAIntegrationTest, ChatProcessorServiceTest, ContextManagerTest, DirectiveProcessorTest, RubyLLMAdapterTest, SessionTest, LocalProvidersTest, UtilityTest, AIAMockingTest, and AIAPropertyBasedTest to include proper Mocha cleanup
|
|
46
|
+
- Test results improved from 2 failures, 2 errors to 0 failures, 0 errors (325 runs, 1018 assertions)
|
|
47
|
+
|
|
48
|
+
### Technical Changes
|
|
49
|
+
- Enhanced test isolation by ensuring all tests using Mocha stubs properly clean up via `super` in teardown
|
|
50
|
+
- Standardized stub usage pattern across test suite for consistency
|
|
51
|
+
- Eliminated stub leakage that caused "unexpected invocation" and "AIA was instantiated in one test but receiving invocations in another" errors
|
|
52
|
+
|
|
4
53
|
## [0.9.21] 2025-10-08
|
|
5
54
|
### Bug Fixes
|
|
6
55
|
- **Checkpoint Directive Output**: Fixed `//checkpoint` directive to return empty string instead of status message (lib/aia/directives/configuration.rb:155)
|
data/README.md
CHANGED
|
@@ -100,6 +100,7 @@ For more information on AIA visit these locations:
|
|
|
100
100
|
- [Example Workflow](#example-workflow)
|
|
101
101
|
- [Roles and System Prompts](#roles-and-system-prompts)
|
|
102
102
|
- [RubyLLM::Tool Support](#rubyllmtool-support)
|
|
103
|
+
- [MCP Server Configuration](#mcp-server-configuration)
|
|
103
104
|
- [Examples & Tips](#examples--tips)
|
|
104
105
|
- [Practical Examples](#practical-examples)
|
|
105
106
|
- [Code Review Prompt](#code-review-prompt)
|
|
@@ -922,6 +923,170 @@ aia --tools examples/tools/mcp/imcp.rb --chat
|
|
|
922
923
|
|
|
923
924
|
These MCP clients require the `ruby_llm-mcp` gem and provide access to external services and data sources through the Model Context Protocol.
|
|
924
925
|
|
|
926
|
+
### MCP Server Configuration
|
|
927
|
+
|
|
928
|
+
AIA supports defining MCP (Model Context Protocol) servers directly in your configuration file. This allows MCP tools to be automatically loaded at startup without needing to specify them on the command line each time.
|
|
929
|
+
|
|
930
|
+
#### Configuration Format
|
|
931
|
+
|
|
932
|
+
Add MCP servers to your `~/.aia/config.yml` file:
|
|
933
|
+
|
|
934
|
+
```yaml
|
|
935
|
+
:mcp_servers:
|
|
936
|
+
- name: "server-name"
|
|
937
|
+
command: "server_command"
|
|
938
|
+
args: ["arg1", "arg2"]
|
|
939
|
+
timeout: 30000 # milliseconds (default: 8000)
|
|
940
|
+
env:
|
|
941
|
+
ENV_VAR: "value"
|
|
942
|
+
```
|
|
943
|
+
|
|
944
|
+
#### Configuration Options
|
|
945
|
+
|
|
946
|
+
| Option | Required | Default | Description |
|
|
947
|
+
|--------|----------|---------|-------------|
|
|
948
|
+
| `name` | Yes | - | Unique identifier for the MCP server |
|
|
949
|
+
| `command` | Yes | - | Executable command (absolute path or found in PATH) |
|
|
950
|
+
| `args` | No | `[]` | Array of command-line arguments |
|
|
951
|
+
| `timeout` | No | `8000` | Connection timeout in milliseconds |
|
|
952
|
+
| `env` | No | `{}` | Environment variables for the server process |
|
|
953
|
+
|
|
954
|
+
#### Example: GitHub MCP Server
|
|
955
|
+
|
|
956
|
+
The GitHub MCP server provides access to GitHub repositories, issues, pull requests, and more:
|
|
957
|
+
|
|
958
|
+
```yaml
|
|
959
|
+
# ~/.aia/config.yml
|
|
960
|
+
:mcp_servers:
|
|
961
|
+
- name: "github"
|
|
962
|
+
command: "github-mcp-server"
|
|
963
|
+
args: ["stdio"]
|
|
964
|
+
timeout: 15000
|
|
965
|
+
env:
|
|
966
|
+
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_your_token_here"
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
**Setup:**
|
|
970
|
+
```bash
|
|
971
|
+
# Install GitHub MCP server (macOS)
|
|
972
|
+
brew install github-mcp-server
|
|
973
|
+
|
|
974
|
+
# Or via npm
|
|
975
|
+
npm install -g @anthropic/github-mcp-server
|
|
976
|
+
|
|
977
|
+
# Set your GitHub token (recommended: use environment variable instead of config)
|
|
978
|
+
export GITHUB_PERSONAL_ACCESS_TOKEN="ghp_your_token_here"
|
|
979
|
+
```
|
|
980
|
+
|
|
981
|
+
#### Example: Hierarchical Temporal Memory (HTM)
|
|
982
|
+
|
|
983
|
+
```shell
|
|
984
|
+
gem install htm
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
See the [full HTM documentation](https://madbomber.github.io/htm) for database configuration and system environment variable usage.
|
|
988
|
+
|
|
989
|
+
A custom Ruby-based MCP server for accessing database-backed long term memory:
|
|
990
|
+
|
|
991
|
+
```yaml
|
|
992
|
+
# ~/.aia/config.yml
|
|
993
|
+
:mcp_servers:
|
|
994
|
+
- name: "htm"
|
|
995
|
+
command: "htm_mcp.rb"
|
|
996
|
+
args: ["stdio"]
|
|
997
|
+
timeout: 30000
|
|
998
|
+
env:
|
|
999
|
+
HTM_DBURL: "postgres://localhost:5432/htm_development"
|
|
1000
|
+
...
|
|
1001
|
+
```
|
|
1002
|
+
|
|
1003
|
+
**Notes:**
|
|
1004
|
+
- The `command` can be just the executable name if it's in your PATH
|
|
1005
|
+
- AIA automatically resolves command paths, so you don't need absolute paths
|
|
1006
|
+
- Environment variables in the `env` section are passed only to that MCP server process
|
|
1007
|
+
|
|
1008
|
+
#### Example: Multiple MCP Servers
|
|
1009
|
+
|
|
1010
|
+
You can configure multiple MCP servers to provide different capabilities:
|
|
1011
|
+
|
|
1012
|
+
```yaml
|
|
1013
|
+
# ~/.aia/config.yml
|
|
1014
|
+
:mcp_servers:
|
|
1015
|
+
- name: "github"
|
|
1016
|
+
command: "github-mcp-server"
|
|
1017
|
+
args: ["stdio"]
|
|
1018
|
+
env:
|
|
1019
|
+
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_your_token_here"
|
|
1020
|
+
|
|
1021
|
+
- name: "htm"
|
|
1022
|
+
command: "htm_mcp.rb"
|
|
1023
|
+
args: ["stdio"]
|
|
1024
|
+
timeout: 30000
|
|
1025
|
+
env:
|
|
1026
|
+
HTM_DBURL: "postgres://localhost:5432/htm_development"
|
|
1027
|
+
|
|
1028
|
+
- name: "filesystem"
|
|
1029
|
+
command: "filesystem-mcp-server"
|
|
1030
|
+
args: ["stdio", "--root", "/Users/me/projects"]
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
#### Verifying MCP Server Configuration
|
|
1034
|
+
|
|
1035
|
+
When MCP servers are configured, AIA displays them in the startup robot:
|
|
1036
|
+
|
|
1037
|
+
```
|
|
1038
|
+
, ,
|
|
1039
|
+
(\____/) AI Assistant (v0.9.23) is Online
|
|
1040
|
+
(_oo_) gpt-4o-mini (supports tools)
|
|
1041
|
+
(O) using ruby_llm (v1.9.0 MCP v0.6.1)
|
|
1042
|
+
__||__ \) model db was last refreshed on
|
|
1043
|
+
[/______\] / 2025-06-03
|
|
1044
|
+
/ \__AI__/ \/ You can share my tools
|
|
1045
|
+
/ /__\ MCP: github, htm
|
|
1046
|
+
(\ /____\
|
|
1047
|
+
```
|
|
1048
|
+
|
|
1049
|
+
Use the `//tools` directive in chat mode to see all available tools including those from MCP servers:
|
|
1050
|
+
|
|
1051
|
+
```bash
|
|
1052
|
+
aia --chat
|
|
1053
|
+
> //tools
|
|
1054
|
+
|
|
1055
|
+
Available Tools:
|
|
1056
|
+
- github_create_issue: Create a new GitHub issue
|
|
1057
|
+
- github_list_repos: List repositories for the authenticated user
|
|
1058
|
+
- htm_query: Execute a query against the HTM database
|
|
1059
|
+
- htm_insert: Insert a record into HTM
|
|
1060
|
+
...
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
#### Troubleshooting MCP Servers
|
|
1064
|
+
|
|
1065
|
+
If an MCP server fails to load, AIA will display a warning:
|
|
1066
|
+
|
|
1067
|
+
```
|
|
1068
|
+
WARNING: MCP server 'github' command not found: github-mcp-server
|
|
1069
|
+
WARNING: MCP server entry missing name or command: {...}
|
|
1070
|
+
ERROR: Failed to load MCP server 'htm': Connection timeout
|
|
1071
|
+
```
|
|
1072
|
+
|
|
1073
|
+
**Common Issues:**
|
|
1074
|
+
|
|
1075
|
+
| Problem | Solution |
|
|
1076
|
+
|---------|----------|
|
|
1077
|
+
| Command not found | Ensure the command is in your PATH or use absolute path |
|
|
1078
|
+
| Connection timeout | Increase the `timeout` value |
|
|
1079
|
+
| Missing environment variables | Add required env vars to the `env` section |
|
|
1080
|
+
| Server hangs on startup | Check that all required environment variables are set |
|
|
1081
|
+
|
|
1082
|
+
**Debug Mode:**
|
|
1083
|
+
|
|
1084
|
+
Enable debug mode to see detailed MCP server loading information:
|
|
1085
|
+
|
|
1086
|
+
```bash
|
|
1087
|
+
aia --debug --chat
|
|
1088
|
+
```
|
|
1089
|
+
|
|
925
1090
|
**Shared Tools Collection:**
|
|
926
1091
|
AIA can use the [shared_tools gem](https://github.com/madbomber/shared_tools) which provides a curated collection of commonly-used tools (aka functions) via the --require option.
|
|
927
1092
|
|
data/lib/aia/config/base.rb
CHANGED
|
@@ -140,6 +140,7 @@ module AIA
|
|
|
140
140
|
config = tailor_the_config(config)
|
|
141
141
|
load_libraries(config)
|
|
142
142
|
load_tools(config)
|
|
143
|
+
load_mcp_servers(config)
|
|
143
144
|
|
|
144
145
|
if config.dump_file
|
|
145
146
|
dump_config(config, config.dump_file)
|
|
@@ -192,6 +193,64 @@ module AIA
|
|
|
192
193
|
exit(1) if exit_on_error
|
|
193
194
|
end
|
|
194
195
|
|
|
196
|
+
def load_mcp_servers(config)
|
|
197
|
+
servers = config.mcp_servers
|
|
198
|
+
|
|
199
|
+
return config if servers.nil? || (servers.respond_to?(:empty?) && servers.empty?)
|
|
200
|
+
|
|
201
|
+
servers.each do |server|
|
|
202
|
+
name = server[:name] || server["name"]
|
|
203
|
+
command = server[:command] || server["command"]
|
|
204
|
+
args = server[:args] || server["args"] || []
|
|
205
|
+
env = server[:env] || server["env"] || {}
|
|
206
|
+
timeout = server[:timeout] || server["timeout"] || 8000 # default 8 seconds in ms
|
|
207
|
+
|
|
208
|
+
unless name && command
|
|
209
|
+
STDERR.puts "WARNING: MCP server entry missing name or command: #{server.inspect}"
|
|
210
|
+
next
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Resolve command path if not absolute
|
|
214
|
+
resolved_command = resolve_command_path(command)
|
|
215
|
+
unless resolved_command
|
|
216
|
+
STDERR.puts "WARNING: MCP server '#{name}' command not found: #{command}"
|
|
217
|
+
next
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
begin
|
|
221
|
+
RubyLLM::MCP.add_client(
|
|
222
|
+
name: name,
|
|
223
|
+
transport_type: :stdio,
|
|
224
|
+
request_timeout: timeout,
|
|
225
|
+
config: {
|
|
226
|
+
command: resolved_command,
|
|
227
|
+
args: args,
|
|
228
|
+
env: env
|
|
229
|
+
}
|
|
230
|
+
)
|
|
231
|
+
rescue => e
|
|
232
|
+
STDERR.puts "ERROR: Failed to load MCP server '#{name}': #{e.message}"
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
config
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def resolve_command_path(command)
|
|
240
|
+
# If already absolute path, verify it exists
|
|
241
|
+
if command.start_with?('/')
|
|
242
|
+
return File.executable?(command) ? command : nil
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Search in PATH
|
|
246
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |dir|
|
|
247
|
+
full_path = File.join(dir, command)
|
|
248
|
+
return full_path if File.executable?(full_path)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
nil
|
|
252
|
+
end
|
|
253
|
+
|
|
195
254
|
# envar values are always String object so need other config
|
|
196
255
|
# layers to know the prompter type for each key's value
|
|
197
256
|
def envar_options(default, cli_config)
|
data/lib/aia/config/defaults.rb
CHANGED
data/lib/aia/utility.rb
CHANGED
|
@@ -13,6 +13,15 @@ module AIA
|
|
|
13
13
|
AIA.config&.tool_paths && !AIA.config.tool_paths.empty?
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
def mcp_servers?
|
|
17
|
+
AIA.config&.mcp_servers && !AIA.config.mcp_servers.empty?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def mcp_server_names
|
|
21
|
+
return [] unless mcp_servers?
|
|
22
|
+
AIA.config.mcp_servers.map { |s| s[:name] || s["name"] }.compact
|
|
23
|
+
end
|
|
24
|
+
|
|
16
25
|
def supports_tools?
|
|
17
26
|
AIA.config&.client&.model&.supports_functions? || false
|
|
18
27
|
end
|
|
@@ -46,6 +55,8 @@ module AIA
|
|
|
46
55
|
'unknown-model'
|
|
47
56
|
end
|
|
48
57
|
|
|
58
|
+
mcp_line = mcp_servers? ? "MCP: #{mcp_server_names.join(', ')}" : ''
|
|
59
|
+
|
|
49
60
|
puts <<-ROBOT
|
|
50
61
|
|
|
51
62
|
, ,
|
|
@@ -55,7 +66,7 @@ module AIA
|
|
|
55
66
|
__||__ \\) model db was last refreshed on
|
|
56
67
|
[/______\\] / #{AIA.config&.last_refresh || 'unknown'}
|
|
57
68
|
/ \\__AI__/ \\/ #{user_tools? ? 'I will also use your tools' : (tools? ? 'You can share my tools' : 'I did not bring any tools')}
|
|
58
|
-
/ /__\\
|
|
69
|
+
/ /__\\ #{mcp_line}
|
|
59
70
|
(\\ /____\\ #{user_tools? && tools? ? 'My Toolbox contains:' : ''}
|
|
60
71
|
ROBOT
|
|
61
72
|
if user_tools? && tools?
|
|
@@ -21,7 +21,11 @@ class OpenStruct
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
# Sets value in result OpenStruct, handling nested OpenStruct and Hash objects
|
|
24
|
+
# Skip nil values to avoid overwriting existing values with nil
|
|
24
25
|
def self.set_value(result, key, value)
|
|
26
|
+
# Skip nil values - don't overwrite existing values with nil
|
|
27
|
+
return if value.nil?
|
|
28
|
+
|
|
25
29
|
if value.is_a?(OpenStruct) || value.is_a?(Hash)
|
|
26
30
|
current_value = result[key]
|
|
27
31
|
current_value = {} if current_value.nil?
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: aia
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.23
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dewayne VanHoozer
|
|
@@ -477,7 +477,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
477
477
|
- !ruby/object:Gem::Version
|
|
478
478
|
version: '0'
|
|
479
479
|
requirements: []
|
|
480
|
-
rubygems_version:
|
|
480
|
+
rubygems_version: 4.0.0
|
|
481
481
|
specification_version: 4
|
|
482
482
|
summary: Multi-model AI CLI with dynamic prompts, consensus responses, shell & Ruby
|
|
483
483
|
integration, and seamless chat workflows.
|